#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>

using namespace std;

#define _int64 long long

int neigh[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};

int a1[50][50];
int a2[50][50];
int a3[50][50];
int cnt[1000];
vector<pair<int,int> > ans;
vector<pair<int,pair<int,int> > > v1,v2;
pair<int,int> d[50][50];
pair<int,int> pos[50][50];
pair<int,int> p,p1,p2;
int mlim,nlim;

void move2(pair<int,int> tar,pair<int,int> forbid)
{
  int i,x,y,k,bk,bd;
  vector<pair<int,int> > seq;
  if (tar==p) return;
    //cout<<"move2:0:"<<p.first<<" "<<p.second<<" "<<tar.first<<" "<<tar.second<<" "<<forbid.first<<" "<<forbid.second<<endl;
  seq.clear();
  seq.push_back(tar);
  while (tar!=p)
  {
    bd=2000000000;
    for (k=0;k<8;k++)
    {
      x=tar.first+neigh[k][0];
      y=tar.second+neigh[k][1];
      if ((x>=0)&&(x<=mlim)&&(y>=0)&&(y<=nlim)&&((x!=forbid.first)||(y!=forbid.second)))
      {
        if (abs(x-p.first)+abs(y-p.second)<bd)
        {
          bd=abs(x-p.first)+abs(y-p.second);
          bk=k;
        }
      }
    }
    //cout<<bd<<endl;
    tar.first+=neigh[bk][0];
    tar.second+=neigh[bk][1];
    seq.push_back(tar);
    //cout<<tar.first<<" "<<tar.second<<endl;
  }
  for (i=seq.size()-2;i>=0;i--)
  {
    //cout<<"move2:"<<seq[i].first<<" "<<seq[i].second<<endl;
    ans.push_back(seq[i]);
    swap(d[p.first][p.second],d[seq[i].first][seq[i].second]);
    pos[d[p.first][p.second].first][d[p.first][p.second].second]=p;
    pos[d[seq[i].first][seq[i].second].first][d[seq[i].first][seq[i].second].second]=seq[i];
    p=seq[i];
  }
  seq.clear();
}

void move1(pair<int,int> pos,pair<int,int> tarpos)
{
  int i;
  vector<pair<int,int> > seq;
  if (pos==tarpos) return;
    //cout<<"move1:0:"<<pos.first<<" "<<pos.second<<" "<<tarpos.first<<" "<<tarpos.second<<endl;
  seq.clear();
  seq.push_back(tarpos);
  while (tarpos!=pos)
  {
    pair<int,int> tmp=tarpos;
    if (tmp.first!=pos.first)
      tmp.first+=(pos.first-tmp.first)/abs(pos.first-tmp.first);
    if (tmp.second!=pos.second)
      tmp.second+=(pos.second-tmp.second)/abs(pos.second-tmp.second);
    //cout<<tmp.first<<" "<<tmp.second<<endl;
    tarpos=tmp;
    seq.push_back(tarpos);
  }
  for (i=seq.size()-1;i>0;i--)
  {
    //cout<<"move1:1:"<<seq[i-1].first<<" "<<seq[i-1].second<<endl;
    move2(seq[i-1],seq[i]);
    //cout<<"move1:2:"<<seq[i].first<<" "<<seq[i].second<<endl;
    move2(seq[i],make_pair(-1,-1));
  }
  seq.clear();
}

int main()
{
  int i,j,k,l,m,n,dire,b1,x,y;
  scanf("%d%d",&m,&n);
  memset(cnt,0,sizeof(cnt));
  for (i=0;i<m;i++)
    for (j=0;j<n;j++)
    {
      scanf("%d",&a1[i][j]);
      cnt[a1[i][j]]++;
    }
  for (i=0;i<m;i++)
    for (j=0;j<n;j++)
    {
      scanf("%d",&a2[i][j]);
      cnt[a2[i][j]]--;
    }
  for (i=1;i<=900;i++)
    if (cnt[i]!=0)
    {
      printf("-1\n");
      return 0;
    }
  ans.clear();
  if (m==1)
  {
    b1=0;
    for (i=0;i<n;i++)
    {
      for (j=0;j<n;j++)
        if (a1[0][i]==a2[0][j])
        {
          if (i==j) continue;
          for (k=0;k<n;k++)
            a3[0][k]=a1[0][k];
          dire=(j-i)/abs(j-i);
          for (k=i;k!=j;k+=dire)
          {
            swap(a3[0][k],a3[0][k+dire]);
          }
          b1=1;
          for (k=0;k<n;k++)
            if (a2[0][k]!=a3[0][k]) b1=0;

          if (b1==1)
          {
            for (k=i;k!=j+dire;k+=dire)
              ans.push_back(make_pair(0,k));
          }
        }
      if (b1==1) break;
    }
    if (b1==0)
    {
      printf("-1\n");
      return 0;
    }
  }
  else if (n==1)
  {
    b1=0;
    for (i=0;i<m;i++)
    {
      for (j=0;j<m;j++)
        if (a1[i][0]==a2[j][0])
        {
          if (i==j) continue;
          for (k=0;k<m;k++)
            a3[k][0]=a1[k][0];
          dire=(j-i)/abs(j-i);
          for (k=i;k!=j;k+=dire)
          {
            swap(a3[k][0],a3[k+dire][0]);
          }
          b1=1;
          for (k=0;k<m;k++)
            if (a2[k][0]!=a3[k][0]) b1=0;

          if (b1==1)
          {
            for (k=i;k!=j+dire;k+=dire)
              ans.push_back(make_pair(k,0));
          }
        }
      if (b1==1) break;
    }
    if (b1==0)
    {
      printf("-1\n");
      return 0;
    }
  }
  else
  {
    v1.clear();
    v2.clear();
    for (i=0;i<m;i++)
      for (j=0;j<n;j++)
      {
        v1.push_back(make_pair(a1[i][j],make_pair(i,j)));
        v2.push_back(make_pair(a2[i][j],make_pair(i,j)));
      }
    sort(v1.begin(),v1.end());
    sort(v2.begin(),v2.end());
    for (i=0;i<v1.size();i++)
    {
      d[v1[i].second.first][v1[i].second.second]=v2[i].second;
      pos[v2[i].second.first][v2[i].second.second]=v1[i].second;
    }
    p=pos[0][0];
    ans.push_back(p);
    while ((m>2)||(n>2))
    {
      if (m>n)
      {
        mlim=m-1;
        nlim=n;
        for (i=0;i<n;i++)
        {
          p1=pos[m-1][i];
          move1(p1,make_pair(m-1,i));
        }
        m--;
      }
      else
      {
        nlim=n-1;mlim=m;
        for (i=0;i<m;i++)
        {
          p1=pos[i][n-1];
          move1(p1,make_pair(i,n-1));
        }
        n--;
      }
    }
    mlim=2;
    nlim=2;
    //cout<<pos[1][0].first<<" "<<pos[1][0].second<<endl;
    move1(pos[1][0],make_pair(1,0));
    move1(pos[1][1],make_pair(1,1));
    move1(pos[0][1],make_pair(0,1));
  }
  printf("%d\n",(int)ans.size()-1);
  for (i=0;i<ans.size();i++)
    printf("%d %d\n",ans[i].first+1,ans[i].second+1);
  return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <utility>
using namespace std;

const int MaxN = 30;
const int MaxM = 30;
const int MaxS = 900;

int sgn(int x)
{
	if (x < 0)
		return -1;
	else if (x > 0)
		return 1;
	else
		return 0;
}

int n, m;
int a[MaxN + 1][MaxM + 1];
int b[MaxN + 1][MaxM + 1];

vector< pair<int, int> > sol;

void smove(int x, int y) {
	if (!sol.empty())
	{
		swap(a[sol.back().first][sol.back().second], a[x][y]);
		if (sol.size() >= 2 && sol[sol.size() - 2] == make_pair(x, y))
			sol.pop_back();
	}
	sol.push_back(make_pair(x, y));
}

void orzl(int cx, int cy)
{
	if (cx == 1)
	{
		for (int i = 1; i <= cy; i++)
			smove(2, i);
		smove(cx, cy);
		smove(cx, cy - 1);
		for (int i = cy; i >= 1; i--)
			smove(2, i);
	}
	else
	{
		for (int i = 2; i <= cy; i++)
			smove(1, i);
		for (int i = 2; i < cx; i++)
			smove(i, cy);
		smove(cx, cy);
		smove(cx, cy - 1);
		for (int i = cx - 1; i >= 2; i--)
			smove(i, cy);
		for (int i = cy; i >= 2; i--)
			smove(1, i);
	}
	smove(1, 1);
}
void orzr(int cx, int cy)
{
	if (cx == 1)
	{
		for (int i = 1; i <= cy; i++)
			smove(2, i);
		smove(cx, cy);
		smove(cx, cy + 1);
		for (int i = cy; i >= 1; i--)
			smove(2, i);
	}
	else
	{
		for (int i = 2; i <= cy; i++)
			smove(1, i);
		for (int i = 2; i < cx; i++)
			smove(i, cy);
		smove(cx, cy);
		smove(cx, cy + 1);
		for (int i = cx - 1; i >= 2; i--)
			smove(i, cy);
		for (int i = cy; i >= 2; i--)
			smove(1, i);
	}
	smove(1, 1);
}
void orzu(int cx, int cy)
{
	if (cy == 1)
	{
		for (int i = 1; i <= cx; i++)
			smove(i, 2);
		smove(cx, cy);
		smove(cx - 1, cy);
		for (int i = cx; i >= 1; i--)
			smove(i, 2);
	}
	else
	{
		for (int i = 2; i <= cx; i++)
			smove(i, 1);
		for (int i = 2; i < cy; i++)
			smove(cx, i);
		smove(cx, cy);
		smove(cx - 1, cy);
		for (int i = cy - 1; i >= 2; i--)
			smove(cx, i);
		for (int i = cx; i >= 2; i--)
			smove(i, 1);
	}
	smove(1, 1);
}
void orzd(int cx, int cy)
{
	if (cy == 1)
	{
		for (int i = 1; i <= cx; i++)
			smove(i, 2);
		smove(cx, cy);
		smove(cx + 1, cy);
		for (int i = cx; i >= 1; i--)
			smove(i, 2);
	}
	else
	{
		for (int i = 2; i <= cx; i++)
			smove(i, 1);
		for (int i = 2; i < cy; i++)
			smove(cx, i);
		smove(cx, cy);
		smove(cx + 1, cy);
		for (int i = cy - 1; i >= 2; i--)
			smove(cx, i);
		for (int i = cx; i >= 2; i--)
			smove(i, 1);
	}
	smove(1, 1);
}

void orzmove(int sx, int sy, int tx, int ty)
{
	if (sx > tx)
	{
		swap(sx, tx);
		swap(sy, ty);
	}

	for (int i = sx; i < tx; i++)
		orzd(i, sy);

	if (sy == ty)
	{
		for (int i = tx - 1; i > sx; i--)
			orzu(i, sy);
	}
	else if (sy < ty)
	{
		for (int i = sy; i < ty; i++)
			orzr(tx, i);
		for (int i = ty - 1; i > sy; i--)
			orzl(tx, i);
		for (int i = tx; i > sx; i--)
			orzu(i, sy);
	}
	else
	{
		for (int i = sy; i > ty; i--)
			orzl(tx, i);
		for (int i = ty + 1; i < sy; i++)
			orzr(tx, i);
		for (int i = tx; i > sx; i--)
			orzu(i, sy);
	}
}

void handle()
{
	if (n == 1 || m == 1)
	{
		bool rotated = m == 1;
		if (rotated)
		{
			for (int i = 1; i <= n; i++)
				a[1][i] = a[i][1];
			for (int i = 1; i <= n; i++)
				b[1][i] = b[i][1];
			swap(n, m);
		}

		for (int l = 1; l <= m; l++)
			for (int r = l; r <= m; r++)
			{
				bool ok = true;
				for (int i = 1; i <= m; i++)
				{
					int c;
					if (i < l)
						c = a[1][i];
					else if (i < r)
						c = a[1][i + 1];
					else if (i == r)
						c = a[1][l];
					else
						c = a[1][i];
					if (b[1][i] != c)
					{
						ok = false;
						break;
					}
				}
				if (ok)
				{
					for (int i = l; i <= r; i++)
					{
						if (!rotated)
							sol.push_back(make_pair(1, i));
						else
							sol.push_back(make_pair(i, 1));
					}
					return;
				}
			}
		for (int l = 1; l <= m; l++)
			for (int r = l; r <= m; r++)
			{
				bool ok = true;
				for (int i = 1; i <= m; i++)
				{
					int c;
					if (i < l)
						c = a[1][i];
					else if (i == l)
						c = a[1][r];
					else if (i <= r)
						c = a[1][i - 1];
					else
						c = a[1][i];
					if (b[1][i] != c)
					{
						ok = false;
						break;
					}
				}
				if (ok)
				{
					for (int i = r; i >= l; i--)
					{
						if (!rotated)
							sol.push_back(make_pair(1, i));
						else
							sol.push_back(make_pair(i, 1));
					}
					return;
				}
			}
		return;
	}

	int cx = -1, cy;
	for (int x = 1; x <= n && cx == -1; x++)
		for (int y = 1; y <= m && cx == -1; y++)
			if (a[x][y] == b[1][1])
				cx = x, cy = y;
	if (cx == -1)
		return;

	for (int i = cx; i > 1; i--)
		smove(i, cy);
	for (int i = cy; i >= 1; i--)
		smove(1, i);

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			cx = -1;
			for (int x = i; x <= n && cx == -1; x++)
				for (int y = x == i ? j : 1; y <= m && cx == -1; y++)
					if (a[x][y] == b[i][j])
						cx = x, cy = y;
			if (cx == -1)
			{
				sol.clear();
				return;
			}
			if (cx == i && cy == j)
				continue;
			orzmove(cx, cy, i, j);
		}
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &b[i][j]);

	handle();

	cout << (int)sol.size() - 1 << endl;
	for (int i = 0; i < (int)sol.size(); i++)
		printf("%d %d\n", sol[i].first, sol[i].second);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <utility>
using namespace std;

const int MaxN = 30;
const int MaxM = 30;
const int MaxS = 900;

int sgn(int x)
{
	if (x < 0)
		return -1;
	else if (x > 0)
		return 1;
	else
		return 0;
}

int n, m;
int a[MaxN + 1][MaxM + 1];
int b[MaxN + 1][MaxM + 1];

vector< pair<int, int> > sol;

void smove(int x, int y) {
	if (!sol.empty())
	{
		swap(a[sol.back().first][sol.back().second], a[x][y]);
		if (sol.size() >= 2 && sol[sol.size() - 2] == make_pair(x, y))
		{
			sol.pop_back();
			return;
		}
	}
	sol.push_back(make_pair(x, y));
}

void orzl(int cx, int cy)
{
	if (cx == 1)
	{
		for (int i = 1; i <= cy; i++)
			smove(2, i);
		smove(cx, cy);
		smove(cx, cy - 1);
		for (int i = cy; i >= 1; i--)
			smove(2, i);
	}
	else
	{
		for (int i = 2; i <= cy; i++)
			smove(1, i);
		for (int i = 2; i < cx; i++)
			smove(i, cy);
		smove(cx, cy);
		smove(cx, cy - 1);
		for (int i = cx - 1; i >= 2; i--)
			smove(i, cy);
		for (int i = cy; i >= 2; i--)
			smove(1, i);
	}
	smove(1, 1);
}
void orzr(int cx, int cy)
{
	if (cx == 1)
	{
		for (int i = 1; i <= cy; i++)
			smove(2, i);
		smove(cx, cy);
		smove(cx, cy + 1);
		for (int i = cy; i >= 1; i--)
			smove(2, i);
	}
	else
	{
		for (int i = 2; i <= cy; i++)
			smove(1, i);
		for (int i = 2; i < cx; i++)
			smove(i, cy);
		smove(cx, cy);
		smove(cx, cy + 1);
		for (int i = cx - 1; i >= 2; i--)
			smove(i, cy);
		for (int i = cy; i >= 2; i--)
			smove(1, i);
	}
	smove(1, 1);
}
void orzu(int cx, int cy)
{
	if (cy == 1)
	{
		for (int i = 1; i <= cx; i++)
			smove(i, 2);
		smove(cx, cy);
		smove(cx - 1, cy);
		for (int i = cx; i >= 1; i--)
			smove(i, 2);
	}
	else
	{
		for (int i = 2; i <= cx; i++)
			smove(i, 1);
		for (int i = 2; i < cy; i++)
			smove(cx, i);
		smove(cx, cy);
		smove(cx - 1, cy);
		for (int i = cy - 1; i >= 2; i--)
			smove(cx, i);
		for (int i = cx; i >= 2; i--)
			smove(i, 1);
	}
	smove(1, 1);
}
void orzd(int cx, int cy)
{
	if (cy == 1)
	{
		for (int i = 1; i <= cx; i++)
			smove(i, 2);
		smove(cx, cy);
		smove(cx + 1, cy);
		for (int i = cx; i >= 1; i--)
			smove(i, 2);
	}
	else
	{
		for (int i = 2; i <= cx; i++)
			smove(i, 1);
		for (int i = 2; i < cy; i++)
			smove(cx, i);
		smove(cx, cy);
		smove(cx + 1, cy);
		for (int i = cy - 1; i >= 2; i--)
			smove(cx, i);
		for (int i = cx; i >= 2; i--)
			smove(i, 1);
	}
	smove(1, 1);
}

void orzmove(int sx, int sy, int tx, int ty)
{
	if (sx > tx)
	{
		swap(sx, tx);
		swap(sy, ty);
	}

	for (int i = sx; i < tx; i++)
		orzd(i, sy);

	if (sy == ty)
	{
		for (int i = tx - 1; i > sx; i--)
			orzu(i, sy);
	}
	else if (sy < ty)
	{
		for (int i = sy; i < ty; i++)
			orzr(tx, i);
		for (int i = ty - 1; i > sy; i--)
			orzl(tx, i);
		for (int i = tx; i > sx; i--)
			orzu(i, sy);
	}
	else
	{
		for (int i = sy; i > ty; i--)
			orzl(tx, i);
		for (int i = ty + 1; i < sy; i++)
			orzr(tx, i);
		for (int i = tx; i > sx; i--)
			orzu(i, sy);
	}
}

void handle()
{
	if (n == 1 || m == 1)
	{
		bool rotated = m == 1;
		if (rotated)
		{
			for (int i = 1; i <= n; i++)
				a[1][i] = a[i][1];
			for (int i = 1; i <= n; i++)
				b[1][i] = b[i][1];
			swap(n, m);
		}

		for (int l = 1; l <= m; l++)
			for (int r = l; r <= m; r++)
			{
				bool ok = true;
				for (int i = 1; i <= m; i++)
				{
					int c;
					if (i < l)
						c = a[1][i];
					else if (i < r)
						c = a[1][i + 1];
					else if (i == r)
						c = a[1][l];
					else
						c = a[1][i];
					if (b[1][i] != c)
					{
						ok = false;
						break;
					}
				}
				if (ok)
				{
					for (int i = l; i <= r; i++)
					{
						if (!rotated)
							sol.push_back(make_pair(1, i));
						else
							sol.push_back(make_pair(i, 1));
					}
					return;
				}
			}
		for (int l = 1; l <= m; l++)
			for (int r = l; r <= m; r++)
			{
				bool ok = true;
				for (int i = 1; i <= m; i++)
				{
					int c;
					if (i < l)
						c = a[1][i];
					else if (i == l)
						c = a[1][r];
					else if (i <= r)
						c = a[1][i - 1];
					else
						c = a[1][i];
					if (b[1][i] != c)
					{
						ok = false;
						break;
					}
				}
				if (ok)
				{
					for (int i = r; i >= l; i--)
					{
						if (!rotated)
							sol.push_back(make_pair(1, i));
						else
							sol.push_back(make_pair(i, 1));
					}
					return;
				}
			}
		return;
	}

	int cx = -1, cy;
	for (int x = 1; x <= n && cx == -1; x++)
		for (int y = 1; y <= m && cx == -1; y++)
			if (a[x][y] == b[1][1])
				cx = x, cy = y;
	if (cx == -1)
		return;

	for (int i = cx; i > 1; i--)
		smove(i, cy);
	for (int i = cy; i >= 1; i--)
		smove(1, i);

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			cx = -1;
			for (int x = i; x <= n && cx == -1; x++)
				for (int y = x == i ? j : 1; y <= m && cx == -1; y++)
					if (a[x][y] == b[i][j])
						cx = x, cy = y;
			if (cx == -1)
			{
				sol.clear();
				return;
			}
			if (cx == i && cy == j)
				continue;
			orzmove(cx, cy, i, j);
		}
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &b[i][j]);

	handle();

	cout << (int)sol.size() - 1 << endl;
	for (int i = 0; i < (int)sol.size(); i++)
		printf("%d %d\n", sol[i].first, sol[i].second);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define files(x) freopen(x ".in", "r", stdin); freopen(x ".out", "w", stdout);
#define input freopen("input.txt", "r", stdin)
#define output freopen("output.txt", "w", stdout)
#define io input; output;
#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ms(x) memset(x, 0, sizeof(x));
#define sqr(a) ((a) * (a))
#define endl "\n"
#define mod % 1000000007
#define x first
#define y second
#define Point pair<int, int>
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<ii, ii> iii;
typedef long double ld;
const ld E = 1e-4;
const int MOD = 1e9 + 7;

#ifdef LOCAL
const ll MAX = 100;
#else
const ll MAX = 1e5 + 1;
#endif

int n, m, a[30][30], b[30][30], X[] = { 0, 1, 0, -1, -1, 1, -1, 1 }, Y[] = { 1, 0, -1,
        0, 1, 1, -1, -1 }, x, y;
ii prev[30][30], d[1000];
bool setted[30][30];
vector<ii> ans;

void check() {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (a[i][j] != b[i][j])
                return;
    cout << ans.size() - 1 << endl;
    for(int i = 0; i < (int) ans.size(); i++){
        cout << (ans[i].first + 1) << " " << (ans[i].second + 1) << endl;
    }
    exit(0);
}

void update(ii p) {
    int t = a[p.x][p.y];
    a[p.x][p.y] = a[x][y];
    a[x][y] = t;
    ans.push_back(p);
    x = p.x;
    y = p.y;
}

void sorry() {
    cout << -1;
    exit(0);
}

void go(int p, int q) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            prev[i][j] = make_pair(-1, -1);

    int l = 0, r = 0;
    d[0] = make_pair(x, y);
    while (l <= r) {
        int x1 = d[l].x;
        int y1 = d[l].y;
        l++;
        for (int i = 0; i < 8; i++) {
            int x2 = x1 + X[i];
            int y2 = y1 + Y[i];
            if (0 <= x2 && x2 < n && 0 <= y2 && y2 < m && !setted[x2][y2]
                    && prev[x2][y2] == Point(-1, -1)) {
                prev[x2][y2] = Point(x1, y1);
                d[++r] = Point(x2, y2);
            }
        }
    }
    Point po = Point(p, q);
    l = 0;
    Point end = Point(x, y);
    while (po != end) {
        d[l++] = po;
        po = prev[po.x][po.y];
    }

    while (l != 0) {
        po = d[--l];
        update(po);
    }
}

void swapA(Point p1, Point p2) {
    Point p = p1;
    while (true) {
        go(p.x, p.y);
        p = ans[ans.size() - 2];
        if (p == p2) {
            return;
        }
        setted[p.x][p.y] = true;
        go(p2.x, p2.y);
        setted[p.x][p.y] = false;
    }
}

void solve(int x1, int y1) {
    go(x1, y1);
    Point p = Point(-1, -1);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if ((i != x1 || j != y1) && !setted[i][j] && a[i][j] == b[x1][y1])
                p = Point(i, j);
    if (p == Point(-1, -1))
        sorry();
    swapA(p, Point(x1, y1));
    setted[x1][y1] = true;
}

int main() {

    sync;

#ifdef LOCAL
    input;
#else

#endif

    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            cin >> a[i][j];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            cin >> b[i][j];
    }

    if (n == 1 || m == 1) {

        if (n == 1) {

            int l = -1, r = -1;
            for (int i = 0; i < m; i++)
            if (a[0][i] != b[0][i]) {
                if (l == -1)
                l = i;
                r = i;
            }
            if (a[0][l] == b[0][r]) {
                bool ok = true;
                for (int i = l; i < r; i++) {
                    if (b[0][i] != a[0][i + 1])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        a[0][i] = b[0][i];
                        ans.push_back(Point(0, i));
                    }
                    check();
                }
            } else if (a[0][r] == b[0][l]) {
                bool ok = true;
                for (int i = l + 1; i <= r; i++) {
                    if (b[0][i] != a[0][i - 1])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        int j = r - (i - l);
                        a[0][j] = b[0][j];
                        ans.push_back(Point(0, j));
                    }
                    check();
                }
            }

        } else {

            int l = -1, r = -1;
            for (int i = 0; i < n; i++)
            if (a[i][0] != b[i][0]) {
                if (l == -1)
                l = i;
                r = i;
            }
            if (a[l][0] == b[r][0]) {
                bool ok = true;
                for (int i = l; i < r; i++) {
                    if (b[i][0] != a[i + 1][0])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        a[i][0] = b[i][0];
                        ans.push_back(Point(i, 0));
                    }
                    check();
                }
            } else if (a[r][0] == b[l][0]) {
                bool ok = true;
                for (int i = l + 1; i <= r; i++) {
                    if (b[i][0] != a[i - 1][0])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        int j = r - (i - l);
                        a[j][0] = b[j][0];
                        ans.push_back(Point(j, 0));
                    }
                    check();
                }
            }

        }
        sorry();
    }

    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    if (a[i][j] == b[n - 1][m - 1]) {
        x = i;
        y = j;
    }

    ans.push_back(Point(x, y));

    for (int i = 0; i < n - 2; i++)
    for (int j = 0; j < m; j++)
    solve(i, j);
    for (int i = 0; i < m - 1; i++) {
        solve(n - 2, i);
        solve(n - 1, i);
    }
    check();

    if (x == n - 1) {
        update(Point(x - 1, y));
    } else {
        update(Point(x + 1, y));
    }
    check();

    sorry();

}


#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define files(x) freopen(x ".in", "r", stdin); freopen(x ".out", "w", stdout);
#define input freopen("input.txt", "r", stdin)
#define output freopen("output.txt", "w", stdout)
#define io input; output;
#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ms(x) memset(x, 0, sizeof(x));
#define sqr(a) ((a) * (a))
#define endl "\n"
#define mod % 1000000007
#define x first
#define y second
#define Point pair<int, int   >
typedef long long ll;
typedef pair<int, int
        > ii;
typedef pair<ii, ii> iii;
typedef long double ld;
const ld E = 1e-4;
const int MOD = 1e9 + 7;

#ifdef LOCAL
const ll MAX = 100;
#else
const ll MAX = 1e5 + 1;
#endif

int n, m, a[30][30], b[30][30], X[] = { 0, 1, 0, -1, -1, 1, -1, 1 }, Y[] = { 1, 0, -1,
        0, 1, 1, -1, -1 }, x, y;
ii previ[30][30], d[1000];
bool setted[30][30];
vector<ii> ans;

void check() {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (a[i][j] != b[i][j])
                return;
    cout << ans.size() - 1 << endl;
    for(int i = 0; i < (int) ans.size(); i++){
        cout << (ans[i].first + 1) << " " << (ans[i].second + 1) << endl;
    }
    exit(0);
}

void update(ii p) {
    int t = a[p.x][p.y];
    a[p.x][p.y] = a[x][y];
    a[x][y] = t;
    ans.push_back(p);
    x = p.x;
    y = p.y;
}

void sorry() {
    cout << -1;
    exit(0);
}

void go(int p, int q) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            previ[i][j] = make_pair(-1, -1);

    int l = 0, r = 0;
    d[0] = make_pair(x, y);
    while (l <= r) {
        int x1 = d[l].x;
        int y1 = d[l].y;
        l++;
        for (int i = 0; i < 8; i++) {
            int x2 = x1 + X[i];
            int y2 = y1 + Y[i];
            if (0 <= x2 && x2 < n && 0 <= y2 && y2 < m && !setted[x2][y2]
                    && previ[x2][y2] == Point(-1, -1)) {
                previ[x2][y2] = Point(x1, y1);
                d[++r] = Point(x2, y2);
            }
        }
    }
    Point po = Point(p, q);
    l = 0;
    Point end = Point(x, y);
    while (po != end) {
        d[l++] = po;
        po = previ[po.x][po.y];
    }

    while (l != 0) {
        po = d[--l];
        update(po);
    }
}

void swapA(Point p1, Point p2) {
    Point p = p1;
    while (true) {
        go(p.x, p.y);
        p = ans[ans.size() - 2];
        if (p == p2) {
            return;
        }
        setted[p.x][p.y] = true;
        go(p2.x, p2.y);
        setted[p.x][p.y] = false;
    }
}

void solve(int x1, int y1) {
    go(x1, y1);
    Point p = Point(-1, -1);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if ((i != x1 || j != y1) && !setted[i][j] && a[i][j] == b[x1][y1])
                p = Point(i, j);
    if (p == Point(-1, -1))
        sorry();
    swapA(p, Point(x1, y1));
    setted[x1][y1] = true;
}

int main() {

    sync;

    int q = 0;
    q = scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            q = scanf("%d", &a[i][j]);
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            q = scanf("%d", &b[i][j]);
    }

    if (n == 1 || m == 1) {

        if (n == 1) {

            int l = -1, r = -1;
            for (int i = 0; i < m; i++)
            if (a[0][i] != b[0][i]) {
                if (l == -1)
                l = i;
                r = i;
            }
            if (a[0][l] == b[0][r]) {
                bool ok = true;
                for (int i = l; i < r; i++) {
                    if (b[0][i] != a[0][i + 1])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        a[0][i] = b[0][i];
                        ans.push_back(Point(0, i));
                    }
                    check();
                }
            } else if (a[0][r] == b[0][l]) {
                bool ok = true;
                for (int i = l + 1; i <= r; i++) {
                    if (b[0][i] != a[0][i - 1])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        int j = r - (i - l);
                        a[0][j] = b[0][j];
                        ans.push_back(Point(0, j));
                    }
                    check();
                }
            }

        } else {

            int l = -1, r = -1;
            for (int i = 0; i < n; i++)
            if (a[i][0] != b[i][0]) {
                if (l == -1)
                l = i;
                r = i;
            }
            if (a[l][0] == b[r][0]) {
                bool ok = true;
                for (int i = l; i < r; i++) {
                    if (b[i][0] != a[i + 1][0])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        a[i][0] = b[i][0];
                        ans.push_back(Point(i, 0));
                    }
                    check();
                }
            } else if (a[r][0] == b[l][0]) {
                bool ok = true;
                for (int i = l + 1; i <= r; i++) {
                    if (b[i][0] != a[i - 1][0])
                    ok = false;
                }
                if (ok) {
                    for (int i = l; i <= r; i++) {
                        int j = r - (i - l);
                        a[j][0] = b[j][0];
                        ans.push_back(Point(j, 0));
                    }
                    check();
                }
            }

        }
        sorry();
    }

    for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
    if (a[i][j] == b[n - 1][m - 1]) {
        x = i;
        y = j;
    }

    ans.push_back(Point(x, y));

    for (int i = 0; i < n - 2; i++)
    for (int j = 0; j < m; j++)
    solve(i, j);
    for (int i = 0; i < m - 1; i++) {
        solve(n - 2, i);
        solve(n - 1, i);
    }
    check();

    if (x == n - 1) {
        update(Point(x - 1, y));
    } else {
        update(Point(x + 1, y));
    }
    check();

    sorry();

}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <list>
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

int h,w;
int s[30][30];
int t[30][30];

int ret[1000001][2],nret;

void up(int &x,int &y,int &xx,int &yy) { int nx=x-1,ny=y; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void down(int &x,int &y,int &xx,int &yy) { int nx=x+1,ny=y; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void left(int &x,int &y,int &xx,int &yy) { int nx=x,ny=y-1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void right(int &x,int &y,int &xx,int &yy) { int nx=x,ny=y+1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void dl(int &x,int &y,int &xx,int &yy) { int nx=x+1,ny=y-1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void dr(int &x,int &y,int &xx,int &yy) { int nx=x+1,ny=y+1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void ul(int &x,int &y,int &xx,int &yy) { int nx=x-1,ny=y-1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void ur(int &x,int &y,int &xx,int &yy) { int nx=x-1,ny=y+1; ret[nret][0]=nx,ret[nret][1]=ny,++nret; swap(s[x][y],s[nx][ny]); if(nx==xx&&ny==yy) swap(x,xx),swap(y,yy); else x=nx,y=ny; }
void pushdleft(int &x,int &y,int &xx,int &yy) { assert(x==xx-1&&y==yy); dl(x,y,xx,yy); right(x,y,xx,yy); up(x,y,xx,yy); }
void pushdright(int &x,int &y,int &xx,int &yy) { assert(x==xx-1&&y==yy); dr(x,y,xx,yy); left(x,y,xx,yy); up(x,y,xx,yy); }
void pushuright(int &x,int &y,int &xx,int &yy) { assert(x==xx+1&&y==yy); ur(x,y,xx,yy); left(x,y,xx,yy); down(x,y,xx,yy); }
void pushldown(int &x,int &y,int &xx,int &yy) { assert(x==xx&&y==yy+1); dl(x,y,xx,yy); up(x,y,xx,yy); right(x,y,xx,yy); }
void pushrdown(int &x,int &y,int &xx,int &yy) { assert(x==xx&&y==yy-1); dr(x,y,xx,yy); up(x,y,xx,yy); left(x,y,xx,yy); }
void pushrup(int &x,int &y,int &xx,int &yy) { assert(x==xx&&y==yy-1); ur(x,y,xx,yy); down(x,y,xx,yy); left(x,y,xx,yy); }

void print() {
//	REP(i,nret) printf("(%d,%d)",ret[i][0],ret[i][1]); puts("");
	REP(i,h) { REP(j,w) printf("%2d ",s[i][j]); puts(""); } puts("");
}

void greedy() {
	int x=-1,y=-1; REP(i,h) REP(j,w) if(s[i][j]==t[0][0]&&x==-1&&y==-1) x=i,y=j; if(x==-1||y==-1) return;
	ret[nret][0]=x,ret[nret][1]=y,++nret;
	for(int tx=h-1;tx>=2;--tx) REP(ty,w) {
		int sx=-1,sy=-1; REPE(i,tx) FOR(j,i<tx?0:ty,w) if(s[i][j]==t[tx][ty]&&sx==-1&&sy==-1&&(i!=x||j!=y)) sx=i,sy=j; if(sx==-1||sy==-1) return;
//		printf("(%d,%d): (%d,%d)->(%d,%d)\n",x,y,sx,sy,tx,ty); print();
		if(x==tx) up(x,y,sx,sy);
		while(y<sy-1||y<sy&&x!=sx) right(x,y,sx,sy);
		while(y>sy+1||y>sy&&x!=sx) left(x,y,sx,sy);
		if(y!=sy) { if(x==0) down(x,y,sx,sy); else up(x,y,sx,sy); if(y<sy) right(x,y,sx,sy); else left(x,y,sx,sy); }
		while(x<sx-1) down(x,y,sx,sy);
		while(x>sx) up(x,y,sx,sy);
		while(sy<ty) { pushdright(x,y,sx,sy); right(x,y,sx,sy); }
		while(sy>ty) { pushdleft(x,y,sx,sy); left(x,y,sx,sy); }
		if(y==0) right(x,y,sx,sy); else left(x,y,sx,sy);
		while(sx<tx) { down(x,y,sx,sy); if(y<sy) pushrdown(x,y,sx,sy); else pushldown(x,y,sx,sy); }
	}
	for(int ty=w-1;ty>=2;--ty) REP(tx,2) {
		int sx=-1,sy=-1; REPE(j,ty) FOR(i,j<ty?0:tx,2) if(s[i][j]==t[tx][ty]&&sx==-1&&sy==-1&&(i!=x||j!=y)) sx=i,sy=j; if(sx==-1||sy==-1) return;
//		printf("(%d,%d): (%d,%d)->(%d,%d)\n",x,y,sx,sy,tx,ty); print();
		if(y==ty) left(x,y,sx,sy);
		while(x<sx&&y!=sy) down(x,y,sx,sy);
		while(x>sx&&y!=sy) up(x,y,sx,sy);
		if(x!=sx) { if(y==0) right(x,y,sx,sy); else left(x,y,sx,sy); if(x<sx) down(x,y,sx,sy); else up(x,y,sx,sy); }
		while(y<sy-1) right(x,y,sx,sy);
		while(y>sy) left(x,y,sx,sy);
		while(sx<tx) { pushrdown(x,y,sx,sy); down(x,y,sx,sy); }
		while(sx>tx) { pushrup(x,y,sx,sy); up(x,y,sx,sy); }
		if(x==0) down(x,y,sx,sy); else up(x,y,sx,sy);
		while(sy<ty) { right(x,y,sx,sy); if(x<sx) pushdright(x,y,sx,sy); else pushuright(x,y,sx,sy); }
	}
	{
		int sx=-1,sy=-1;
		while(x>0) up(x,y,sx,sy);
		while(y>0) left(x,y,sx,sy);
		if(s[0][1]==t[1][1]) sx=0,sy=1,pushrdown(x,y,sx,sy);
		else if(s[1][0]==t[1][1]) sx=1,sy=0,pushdright(x,y,sx,sy);
		else if(s[1][1]!=t[1][1]) return;
		if(s[1][0]==t[0][1]) { sx=1,sy=0; right(x,y,sx,sy); dl(x,y,sx,sy); up(x,y,sx,sy); }
		else if(s[0][1]!=t[0][1]) return;
	}
}

void line(int dx,int dy) {
	int lx=0,ly=0; while(lx<h&&ly<w&&s[lx][ly]==t[lx][ly]) lx+=dx,ly+=dy; if(lx>=h||ly>=w) return;
	int hx=h-1,hy=w-1; while(hx>=0&&hy>=0&&s[hx][hy]==t[hx][hy]) hx-=dx,hy-=dy; if(hx<0||hy<0) return;
	bool back=true; for(int x=lx,y=ly;x+dx<=hx&&y+dy<=hy;x+=dx,y+=dy) if(s[x][y]!=t[x+dx][y+dy]) back=false;
	int cnt=hx-lx+hy-ly;
	ret[nret][0]=!back?lx:hx,ret[nret][1]=!back?ly:hy,++nret;
	if(!back) REP(i,cnt) if(dx==0) right(lx,ly,hx,hy); else down(lx,ly,hx,hy);
	else REP(i,cnt) if(dx==0) left(hx,hy,lx,ly); else up(hx,hy,lx,ly);
}

int p[900];

void run() {
	scanf("%d%d",&h,&w);
	REP(i,h) REP(j,w) scanf("%d",&s[i][j]);
	REP(i,h) REP(j,w) scanf("%d",&t[i][j]);
	nret=0;
	//h=30,w=30; REP(i,h*w) p[i]=i; REP(i,h*w) { int j=i+rand()%(h*w-i); swap(p[i],p[j]); } REP(i,h) REP(j,w) s[i][j]=p[i*w+j],t[i][j]=i*w+j;
	//print();
	if(h==1) {
		line(0,+1);
	} else if(w==1) {
		line(+1,0);
	} else {
		greedy();
	}
	//print();
	bool ok=true; REP(i,h) REP(j,w) if(s[i][j]!=t[i][j]) ok=false; if(!ok) { printf("-1\n"); return; }
	printf("%d\n",nret-1);
	REP(i,nret) printf("%d %d\n",ret[i][0]+1,ret[i][1]+1);
}

int main() {
	run();
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

int n,m;
int grid[32][32];
int goal[32][32];
vector< pair<int,int> > moves;
bool blocked[32][32];

int ctr1[1001];
int ctr2[1001];

int begx=1,begy=1;
int curx,cury;

pair<int,int> Path[1001];
int L=0;

pair<int,int> BlockPath[1001];
int bL=0;

bool FoundPath=false;
int UTFO[32][32];
int Key=1;

bool First=true;

void GetPath(int cx,int cy,int gx,int gy)
{
    //cout<<"Currently at "<<cx<<";"<<cy<<" trying to reach "<<gx<<" "<<gy<<endl;

    if (UTFO[cx][cy]==Key)
    return;

    if (cx==gx && cy==gy)
    {
        FoundPath=true;
        return;
    }

    UTFO[cx][cy]=Key;

    int mx,my;

    if (cx<gx)
    mx=1;
    else if (cx>gx)
    mx=-1;
    else
    mx=0;

    if (cy<gy)
    my=1;
    else if (cy>gy)
    my=-1;
    else
    my=0;

    //cout<<mx<<".;."<<my<<endl;

    if (!blocked[cx+mx][cy+my])
    {
        L++;
        Path[L]=make_pair(cx+mx,cy+my);
        GetPath(cx+mx,cy+my,gx,gy);
        if (FoundPath)
        return;
        L--;
    }

    if (mx!=0)
    {
        if (!blocked[cx+mx][cy])
        {
            L++;
            Path[L]=make_pair(cx+mx,cy);
            GetPath(cx+mx,cy,gx,gy);
            if (FoundPath)
            return;
            L--;
        }
    }

    ///

    if (my!=0)
    {
        if (!blocked[cx][cy+my])
        {
            L++;
            Path[L]=make_pair(cx,cy+my);
            GetPath(cx,cy+my,gx,gy);
            if (FoundPath)
            return;
            L--;
        }
    }

    ///

    if (mx==0)
    {
        if (!blocked[cx-1][cy+my])
        {
            L++;
            Path[L]=make_pair(cx-1,cy+my);
            GetPath(cx-1,cy+my,gx,gy);
            if (FoundPath)
            return;
            L--;
        }

        if (!blocked[cx+1][cy+my])
        {
            L++;
            Path[L]=make_pair(cx+1,cy+my);
            GetPath(cx+1,cy+my,gx,gy);
            if (FoundPath)
            return;
            L--;
        }
    }

    ///

    if (my==0)
    {
        if (!blocked[cx+mx][cy-1])
        {
            L++;
            Path[L]=make_pair(cx+mx,cy-1);
            GetPath(cx+mx,cy-1,gx,gy);
            if (FoundPath)
            return;
            L--;
        }

        if (!blocked[cx+mx][cy+1])
        {
            L++;
            Path[L]=make_pair(cx+mx,cy+1);
            GetPath(cx+mx,cy+1,gx,gy);
            if (FoundPath)
            return;
            L--;
        }
    }

    if (!blocked[cx-1][cy+my])
    {
        L++;
        Path[L]=make_pair(cx-1,cy+my);
        GetPath(cx-1,cy+my,gx,gy);
        if (FoundPath)
        return;
        L--;
    }

    if (!blocked[cx+1][cy+my])
    {
        L++;
        Path[L]=make_pair(cx+1,cy+my);
        GetPath(cx+1,cy+my,gx,gy);
        if (FoundPath)
        return;
        L--;
    }

    if (!blocked[cx+mx][cy-1])
    {
        L++;
        Path[L]=make_pair(cx+mx,cy-1);
        GetPath(cx+mx,cy-1,gx,gy);
        if (FoundPath)
        return;
        L--;
    }

    if (!blocked[cx+mx][cy+1])
    {
        L++;
        Path[L]=make_pair(cx+mx,cy+1);
        GetPath(cx+mx,cy+1,gx,gy);
        if (FoundPath)
        return;
        L--;
    }

    return;
}

void SWAP(int x1,int y1,int x2,int y2)
{
    int k=grid[x1][y1];
    grid[x1][y1]=grid[x2][y2];
    grid[x2][y2]=k;
    return;
}

void MovePointer(int x,int y)
{
    int i;

    //cout<<"Moving pointer from "<<curx<<";"<<cury<<" to "<<x<<";"<<y<<endl;

    L=0;
    FoundPath=false;
    Key++;
    GetPath(curx,cury,x,y);

    for (i=1;i<=L;i++)
    {
        moves.push_back( make_pair(Path[i].first,Path[i].second) );

        SWAP(curx,cury,Path[i].first,Path[i].second);

        curx=Path[i].first;
        cury=Path[i].second;
    }

    return;
}

void MoveBlock(int x1,int y1,int x2,int y2)
{
    int i;
    int bx=x1,by=y1;

    L=0;
    FoundPath=false;
    Key++;
    GetPath(x1,y1,x2,y2);

    bL=L;
    //cout<<"Path of length "<<L<<endl;
    for (i=1;i<=L;i++)
    {
        //cout<<Path[i].first<<";"<<Path[i].second<<endl;
        BlockPath[i]=Path[i];
    }

    for (i=1;i<=bL;i++)
    {
        //cout<<"Moving the block to "<<BlockPath[i].first<<" "<<BlockPath[i].second<<endl;

        blocked[bx][by]=true;
        MovePointer(BlockPath[i].first,BlockPath[i].second);
        blocked[bx][by]=false;
        MovePointer(bx,by);

        bx=BlockPath[i].first;
        by=BlockPath[i].second;
    }

    return;
}

void RemoveLine()
{
    int i,j,in;
    int s;
    int x,y;

    //cout<<"Removing line "<<n<<endl;
    //cout<<endl;

    for (i=1;i<=m;i++)
    {
        ///Removing [n,i]
        x=-1;
        y=-1;

        for (j=1;j<=n;j++)
        {
            if (j!=n)
            s=1;
            else
            s=i;

            for (in=s;in<=m;in++)
            {
                if (j==curx && in==cury)
                continue;

                if (grid[j][in]==goal[n][i])
                {
                    x=j;
                    y=in;
                    break;
                }
            }

            if (x!=-1)
            break;
        }

        //cout<<"Trying to fill "<<n<<";"<<i<<" with the block at "<<x<<";"<<y<<"("<<grid[x][y]<<")"<<endl;

        MoveBlock(x,y,n,i);

        blocked[n][i]=true;
    }

    n--;
    //cout<<endl<<endl;

    return;
}

///

void RemoveColumn()
{
    int i,j,in;
    int s;
    int x,y;

    //cout<<"Removing column "<<m<<endl;
    //cout<<endl;

    for (i=1;i<=n;i++)
    {
        ///Removing [i,m]
        x=-1;
        y=-1;

        for (j=1;j<=m;j++)
        {
            if (j!=m)
            s=1;
            else
            s=i;

            for (in=s;in<=n;in++)
            {
                if (in==curx && j==cury)
                continue;

                if (grid[in][j]==goal[i][m])
                {
                    x=in;
                    y=j;
                    break;
                }
            }

            if (x!=-1)
            break;
        }

        //cout<<"Trying to fill "<<i<<";"<<m<<" with the block at "<<x<<";"<<y<<endl;

        MoveBlock(x,y,i,m);

        blocked[i][m]=true;
    }

    m--;
    //cout<<endl<<endl;

    return;
}

///

int A[32];
int B[32];
int Len;

void S(int a,int b)
{
    int d=A[a];
    A[a]=A[b];
    A[b]=d;
    return;
}

bool Equal()
{
    int i;

    for (i=1;i<=Len;i++)
    {
        if (A[i]!=B[i])
        return false;
    }

    return true;
}

int main()
{
    //freopen("mytest.txt","r",stdin);
    //freopen("myans.txt","w",stdout);

    int i,j;
    int L,R;

    scanf("%d %d",&n,&m);

    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            scanf("%d",&grid[i][j]);
            ctr1[ grid[i][j] ]++;
        }
    }

    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            scanf("%d",&goal[i][j]);
            ctr2[ goal[i][j] ]++;
        }
    }

    for (i=1;i<=900;i++)
    {
        if (ctr1[i]!=ctr2[i])
        {
            printf("-1\n");
            return 0;
        }
    }

    for (i=0;i<=31;i++)
    {
        for (j=0;j<=31;j++)
        {
            blocked[i][j]=false;
            if (i<1 || i>n || j<1 || j>m)
            blocked[i][j]=true;
        }
    }

    begx=-1;
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            if (grid[i][j]==goal[1][1])
            {
                begx=i;
                begy=j;
                break;
            }
        }
        if (begx!=-1)
        break;
    }

    curx=begx;
    cury=begy;

    if (n>=2 && m>=2)
    {
        //cout<<"Inititally at "<<curx<<";"<<cury<<endl;

        while(n>2)
        {
            RemoveLine();
        }

        while(m>2)
        {
            RemoveColumn();
        }
    }
    else
    {
        if (n==1)
        {
            Len=m;

            for (i=1;i<=m;i++)
            {
                A[i]=grid[1][i];
                B[i]=goal[1][i];
            }
        }
        else if (m==1)
        {
            Len=n;

            for (i=1;i<=n;i++)
            {
                A[i]=grid[i][1];
                B[i]=goal[i][1];
            }
        }

        L=-1;
        R=-1;

        for (i=1;i<=Len;i++)
        {
            for (j=i+1;j<=Len;j++)
            {
                S(j-1,j);
                if (Equal())
                {
                    L=i;
                    R=j;
                    break;
                }
            }

            if (L!=-1)
            break;

            for (j=Len;j>=i+1;j--)
            {
                S(j-1,j);
            }
        }

        if (L!=-1)
        {
            printf("%d\n",R-L);
            if (n==1)
            printf("%d %d\n",1,L);
            else
            printf("%d %d\n",L,1);

            for (i=L+1;i<=R;i++)
            {
                if (n==1)
                printf("%d %d\n",1,i);
                else
                printf("%d %d\n",i,1);
            }

            return 0;
        }

        ///

        for (i=1;i<=Len;i++)
        {
            for (j=i-1;j>=1;j--)
            {
                S(j,j+1);
                if (Equal())
                {
                    L=i;
                    R=j;
                    break;
                }
            }

            if (L!=-1)
            break;

            for (j=1;j<=i-1;j++)
            {
                S(j,j+1);
            }
        }

        if (L!=-1)
        {
            printf("%d\n",L-R);
            if (n==1)
            printf("%d %d\n",1,L);
            else
            printf("%d %d\n",L,1);

            for (i=L-1;i>=R;i--)
            {
                if (n==1)
                printf("%d %d\n",1,i);
                else
                printf("%d %d\n",i,1);
            }

            return 0;
        }

        ///

        printf("-1\n");
        return 0;
    }

    if (curx!=2 || cury!=2)
    {
        moves.push_back( make_pair(2,2) );
        SWAP(curx,cury,2,2);
    }

    if (grid[1][1]==goal[2][2])
    {
        if (grid[1][2]==goal[1][2]) ///everything is fine
        {
            moves.push_back( make_pair(1,1) );
        }
        else ///1;2 and 2;1 are swapped
        {
            moves.push_back( make_pair(1,2) );
            moves.push_back( make_pair(2,1) );
            moves.push_back( make_pair(2,2) );
            moves.push_back( make_pair(1,1) );
        }
    }
    else if (grid[1][2]==goal[2][2])
    {
        moves.push_back( make_pair(1,2) );

        if (grid[1][1]==goal[1][2])
        {
            moves.push_back( make_pair(1,1) );
        }
        else
        {
            moves.push_back( make_pair(2,1) );
            moves.push_back( make_pair(1,1) );
        }
    }
    else ///grid[2][1] == goal[2][2]
    {
        moves.push_back( make_pair(2,1) );

        if (grid[1][1]==goal[2][1])
        {
            moves.push_back( make_pair(1,1) );
        }
        else
        {
            moves.push_back( make_pair(1,2) );
            moves.push_back( make_pair(1,1) );
        }
    }

    printf("%d\n",moves.size());
    printf("%d %d\n",begx,begy);

    for (i=0;i<moves.size();i++)
    {
        printf("%d %d\n",moves[i].first,moves[i].second);
    }

    return 0;
}


#undef NDEBUG
#ifdef KUVIMAN
#define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cassert>
#include <ctime>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i < int(r); i++)
#define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define ft first
#define sc second
#define X first
#define Y second

using namespace std;

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template<typename X> inline X abs(const X& a) { return a < 0? -a: a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld EPS = 1e-9, PI = acosl(ld(-1));

int sign(int x) {
	if (x < 0) return -1;
	if (x > 0) return +1;
	throw;
}

const int N = 33;
int n, m;
int a[N][N], b[N][N];

pt pos[N][N], who[N][N];

vector<pt> ans;

void step(pt a, pt b) {
	swap(who[a.X][a.Y], who[b.X][b.Y]);
	pos[who[a.X][a.Y].X][who[a.X][a.Y].Y] = a;
	pos[who[b.X][b.Y].X][who[b.X][b.Y].Y] = b;
	ans.pb(b);
}

void moveTo(int x, int y) {
	pt& myPos = pos[0][0];
	while (myPos.X != x)
		step(myPos, pt(myPos.X + sign(x - myPos.X), myPos.Y));
	while (myPos.Y != y)
		step(myPos, pt(myPos.X, myPos.Y + sign(y - myPos.Y)));
}

void doSwap(pt a, pt b) {
	pt c = pos[0][0];
	step(c, a);
	step(a, b);
	step(b, c);
}

void moveX(pt from, int dx) {
	if (from.Y != 0)
		moveTo(from.X, from.Y - 1);
	else {
		moveTo(0, 1);
		moveTo(from.X, 1);
	}
	doSwap(from, pt(from.X + dx, from.Y));
	if (from.Y == 0)
		moveTo(0, 1);
	moveTo(0, 0);
}

void moveY(pt from, int dy) {
	if (from.X != 0)
		moveTo(from.X - 1, from.Y);
	else {
		moveTo(1, 0);
		moveTo(1, from.Y);
	}
	doSwap(from, pt(from.X, from.Y + dy));
	if (from.X == 0)
		moveTo(1, 0);
	moveTo(0, 0);
}

void place(pt from, pt to) {
	while (from.X != to.X) {
		moveX(from, sign(to.X - from.X));
		from.X += sign(to.X - from.X);
	}
	while (from.Y != to.Y) {
		moveY(from, sign(to.Y - from.Y));
		from.Y += sign(to.Y - from.Y);
	}
}

int cur[N][N];
void clear() {
	forn(i, n)
		forn(j, m)
			cur[i][j] = a[i][j];
}
bool ok() {
	forn(i, n)
		forn(j, m)
			if (cur[i][j] != b[i][j])
				return false;
	return true;
}

bool check() {
	clear();
	forn(i, sz(ans) - 1) {
		pt a = ans[i], b = ans[i + 1];
		swap(cur[a.X][a.Y], cur[b.X][b.Y]);
	}
/*	forn(i, n) {
		forn(j, m)
			cerr << cur[i][j] << ' ';
		cerr << endl;
	}*/
	return ok();
}

#ifdef KUVIMAN
//#define GEN
#endif

int buf[N * N];
bool solve() {
#ifdef GEN
	n = m = 30;
	forn(i, n * m)
		buf[i] = rand() % 10;
	forn(i, n)
		forn(j, m)
			a[i][j] = buf[i * m + j];
	random_shuffle(buf, buf + n * m);
	forn(i, n)
		forn(j, m)
			b[i][j] = buf[i * m + j];

	cerr << n << ' ' << m << endl;
	forn(i, n) {
		forn(j, m)
			cerr << a[i][j] << ' ';
		cerr << endl;
	}
	forn(i, n) {
		forn(j, m)
			cerr << b[i][j] << ' ';
		cerr << endl;
	}

#else
	if (scanf("%d%d", &n, &m) != 2)
		return false;
	forn(i, n)
		forn(j, m)
			assert(scanf("%d", &a[i][j]) == 1);
	forn(i, n)
		forn(j, m)
			assert(scanf("%d", &b[i][j]) == 1);
#endif

	int in = n, im = m;

	map<int,queue<pt> > q;

	if (n == 1 || m == 1) {
		if (n == 1) {
			forn(from, m)
				forn(to, m) {
					clear();
					ans.clear();
					for (int j = from; j != to; j += sign(to - j))
						swap(cur[0][j], cur[0][j + sign(to - j)]);
					if (ok()) {
						for (int j = from; j != to; j += sign(to - j))
							ans.pb(pt(0, j));
						ans.pb(pt(0, to));
						goto printAns;
					}
				}
			puts("-1");
		} else {
			forn(from, n)
				forn(to, n) {
					clear();
					ans.clear();
					for (int i = from; i != to; i += sign(to - i))
						swap(cur[i][0], cur[i + sign(to - i)][0]);
					if (ok()) {
						for (int i = from; i != to; i += sign(to - i))
							ans.pb(pt(i, 0));
						ans.pb(pt(to, 0));
						goto printAns;
					}
				}
			puts("-1");
		}
		return true;
	}
	forn(i, n)
		forn(j, m)
			q[a[i][j]].push(pt(i, j));
	forn(i, n)
		forn(j, m) {
			if (q[b[i][j]].empty()) {
				puts("-1");
				return true;
			}
			pos[i][j] = q[b[i][j]].front();
			who[pos[i][j].X][pos[i][j].Y] = pt(i, j);
			q[b[i][j]].pop();
		}

	ans.clear();
	ans.pb(pos[0][0]);
	moveTo(0, 0);
	while (n != 1 || m != 1) {
		if (n < m) {
			forn(i, n) {
			//	cerr << "MOVE FROM " << pos[i][m - 1].X << ' ' << pos[i][m - 1].Y << " to " << i << ' ' << m - 1 << endl;
				if (i == 0 && pos[i][m - 1].Y == 0) {
					place(pos[i][m - 1], pt(1, 0));
					doSwap(pt(1, 0), pt(0, 1));
				} else
    				place(pos[i][m - 1], pt(i, pos[i][m - 1].Y));
    			place(pos[i][m - 1], pt(i, m - 1));
			//	cerr << sz(ans) << endl;
			}
			m--;
			//cerr << "M-- " << sz(ans) << endl;
		} else {
			forn(j, m) {
			//	cerr << "MOVE FROM " << pos[n - 1][j].X << ' ' << pos[n - 1][j].Y << " to " << n - 1 << ' ' << j << endl;
				if (pos[n - 1][j].X == 0 && j == 0) {
					place(pos[n - 1][j], pt(0, 1));
					doSwap(pt(1, 0), pt(0, 1));
				} else
					place(pos[n - 1][j], pt(pos[n - 1][j].X, j));
				place(pos[n - 1][j], pt(n - 1, j));
			//	cerr << sz(ans) << endl;
			}
			n--;
			//cerr << "N-- " << sz(ans) << endl;
		}
		moveTo(0, 0);
	}

	n = in, m = im;

printAns:
	printf("%d\n", sz(ans) - 1);
	forn(i, sz(ans)) {
		printf("%d %d\n", ans[i].X + 1, ans[i].Y + 1);
	}

	assert(check());
	//cerr << sz(ans) << endl;

	return true;
}

int main() {
#ifdef KUVIMAN
	assert(freopen("input.txt", "rt", stdin));
	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << setprecision(10) << fixed;
	cerr << setprecision(5) << fixed;

	while (solve()) {}
//	solve();

#ifdef KUVIMAN
	cerr << "== TIME : " << clock() << " ==" << endl;
#endif
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    memmove(C,A[0],sizeof(C));
    if(memcmp(C,B[0],sizeof(C))==0) {
        return _P("1 1\n");
    }
    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;

    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy)-(ty<cy);
        nx=cx+(tx>cx)-(tx<cx);
        if(F[ny][nx] && ny>cy && nx<cx) ny=cy;
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    memmove(C,A[0],sizeof(C));
    if(memcmp(C,B[0],sizeof(C))==0) {
        return _P("1 1\n");
    }
    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i)
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
        }
        if(X[y][x]<0) return _P("-1\n");
    }

    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(W);

    _P("%d\n",R.size());
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    memmove(C,A[0],sizeof(C));
    if(memcmp(C,B[0],sizeof(C))==0) {
        return _P("1 1\n");
    }
    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;
    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]+1) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
            if(ty==tary && tx==tarx) break;
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;

    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy)-(ty<cy);
        nx=cx+(tx>cx)-(tx<cx);
        if(F[ny][nx] && ny>cy && nx<cx) ny=cy;
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(W-1);

    _P("%d\n",R.size());
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(W-1);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    memmove(C,A[0],sizeof(C));
    if(memcmp(C,B[0],sizeof(C))==0) {
        return _P("1 1\n");
    }
    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    memmove(C,A[0],sizeof(C));
    if(memcmp(C,B[0],sizeof(C))==0) {
        return _P("1 1\n");
    }
    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                _P("%d %d\n",rotate?i+1:1,rotate?1:(i+1));
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    /*
    int x,y;
    _P("%d %d\n",ty,tx);
    FOR(y,H) {
        FOR(x,W) _P("%d ",A[y][x]);
        _P(" : ");
        FOR(x,W) _P("%d ",F[y][x]);
        _P("\n");
    }
    */

    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy)-(ty<cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }
    R.push_back(Y[0][0]*100+X[0][0]);
    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(0);

    _P("%d\n",R.size()-1);
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W;
int A[30][30],B[30][30];
int X[30][30],Y[30][30],F[30][30];
vector<int> R;

void single(bool rotate) {
    int i,j;
    int C[30];

    if(rotate) {
        FOR(i,H) swap(A[0][i],A[i][0]);
        FOR(i,H) swap(B[0][i],B[i][0]);
        swap(H,W);
    }

    FOR(i,W) {
        memmove(C,A[0],sizeof(C));
        for(j=i+1;j<W;j++) {
            swap(C[j],C[j-1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",j-i);
                for(;i<j;i++) _P("%d %d\n",rotate?i+2:1,rotate?1:(i+2));
                return;
            }
        }
        memmove(C,A[0],sizeof(C));
        for(j=i-1;j>=0;j--) {
            swap(C[j],C[j+1]);
            if(memcmp(C,B[0],sizeof(C))==0) {
                _P("%d\n",i-j);
                for(;i>j;i--) _P("%d %d\n",rotate?i:1,rotate?1:i);
                return;
            }
        }
    }
    _P("-1\n");

}

void moveone(int tarx,int tary,int sx,int sy) {
    int D[30][30],from[30][30];
    int x,y,dx,dy,i;
    FOR(x,30) FOR(y,30) D[x][y]=1000;
    D[sy][sx]=0;
    queue<int> Q;

    Q.push(sy*100+sx);
    while(Q.size()) {
        int cy=Q.front()/100, cx=Q.front()%100;
        if(cy==tary && cx==tarx) break;
        Q.pop();
        for(dx=-1;dx<=1;dx++) for(dy=-1;dy<=1;dy++) {
            int tx=cx+dx,ty=cy+dy;
            if(tx<0 || tx>=W || ty<0 || ty>=H || F[ty][tx] || D[ty][tx]<=D[cy][cx]) continue;
            from[ty][tx]=cy*100+cx;
            D[ty][tx]=D[cy][cx]+1;
            Q.push(ty*100+tx);
        }
    }

    vector<int> V;
    while(tarx!=sx || tary!=sy) {
        V.push_back(tary*100+tarx);
        y=tary,x=tarx;
        tary=from[y][x]/100;
        tarx=from[y][x]%100;
    }
    FOR(i,V.size()) {
        tary=V[V.size()-1-i]/100;
        tarx=V[V.size()-1-i]%100;
        int j=A[tary][tarx];

        A[sy][sx]=j;
        A[tary][tarx]=0;

        X[j/W][j%W]=sx;
        Y[j/W][j%W]=sy;
        X[0][0]=sx=tarx;
        Y[0][0]=sy=tary;
        R.push_back(tary*100+tarx);
    }
}

void move(int tx,int ty) {
    F[Y[ty][tx]][X[ty][tx]]=1;
    int x,y;
    while(A[ty][tx] != ty*W+tx) {
        int cx=X[ty][tx],cy=Y[ty][tx];
        int nx,ny;

        ny=cy+(ty>cy);
        nx=cx+(tx>cx)-(tx<cx);
        moveone(nx,ny,X[0][0],Y[0][0]);
        swap(A[cy][cx],A[ny][nx]);
        X[ty][tx]=nx;
        Y[ty][tx]=ny;
        X[0][0]=cx;
        Y[0][0]=cy;
        F[cy][cx]=0;
        F[ny][nx]=1;

        R.push_back(cy*100+cx);
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>H>>W;
    FOR(y,H) FOR(x,W) cin>>A[y][x];
    FOR(y,H) FOR(x,W) cin>>B[y][x];

    if(H==1 || W==1) return single(W==1);
    FOR(y,H) FOR(x,W) A[y][x]+=1000;
    MINUS(X);
    FOR(y,H) FOR(x,W) {
        FOR(i,H) FOR(j,W) if(B[y][x]+1000==A[i][j]) {
            A[i][j]=y*W+x;
            X[y][x]=j;
            Y[y][x]=i;
            B[y][x]=1000;
        }
        if(X[y][x]<0) return _P("-1\n");
    }

    for(y=H-1;y>1;y--) for(x=W-1;x>=0;x--) move(x,y);
    for(x=W-1;x>0;x--) for(y=1;y>=0;y--) move(x,y);
    if(A[0][0]!=0) R.push_back(W);

    _P("%d\n",R.size());
    ITR(it,R) _P("%d %d\n",*it/100+1,*it%100+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
#define x first
#define y second
#define mp make_pair
#define pb push_back

void open()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
}

int dx[8]={-1, 0, 1,-1,0,1,-1,1};
int dy[8]={-1,-1,-1,1, 1,1,0, 0};

class chess
{
	public:
		int ori[33][33],end[33][33],mid[33][33],m,n,a,b,num[2][901];
		bool use[33][33];pii pre[33][33];
		vector<pii> ans;
		void work()
		{
			read();
			all_judge();
			pre_judge();
			if(min(n,m)==1)work1();
			top_judge();
		}
	private:
		void read()
		{
			cin>>n>>m;
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)cin>>ori[i][j];
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)cin>>end[i][j];
		}
		bool all_judge()
		{
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)++num[0][ori[i][j]],++num[1][end[i][j]];
			for(int i=1;i<=900;++i)if(num[0][i]!=num[1][i]){printf("-1\n");exit(0);}
		}
		bool pre_judge()
		{
			for(int i=1;i<=n;++i)
				for(int j=1;j<=m;++j)
					if(ori[i][j]!=end[i][j])return 0;
			printf("0\n");
			exit(0);
		}
		inline pii wr(pii x){printf("%d %d\n",x.x,x.y);return x;}
		inline void print(){printf("%d\n",ans.size()-1);for(int i=0;i<ans.size();++i)wr(ans[i]);exit(0);}
		inline bool judge(){for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(mid[i][j]!=end[i][j])return 0;print();}
		inline void load(){ans.clear();for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)mid[i][j]=ori[i][j];}
		inline bool in(int x,int y){return 1<=x && x<=n && 1<=y && y<=m && !use[x][y];}
		inline void exch(int x,int y)
		{
			swap(mid[ans.back().x][ans.back().y],mid[x][y]);
			ans.pb(mp(x,y));a=x;b=y;
		}
		void work1()
		{
			for(int i=1;i<=max(m,n);++i)
				for(int d=-1;d<2;d+=2)
				{
					load();ans.pb(mp(n==1 ? 1 : i,n==1 ? i : 1));
					for(int k=i+d;1<=k && k<=max(m,n);k+=d)
					{
						exch(n==1 ? 1 : k,n==1 ? k : 1);
						judge();
					}
				}
				printf("-1\n");exit(0);
		}
		void way_to(int x,int y)
		{
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)pre[i][j]=mp(-1,-1);
			queue<pii> q;pii u;
			while(!q.empty())q.pop();
			q.push(mp(a,b));
			while(!q.empty())
			{
				u=q.front();q.pop();
				for(int d=0;d<8;++d)
					if(in(u.x+dx[d],u.y+dy[d]) && pre[u.x+dx[d]][u.y+dy[d]]==mp(-1,-1))
					{
						pre[u.x+dx[d]][u.y+dy[d]]=u;
						q.push(mp(u.x+dx[d],u.y+dy[d]));
					}
			}
			stack<pii> s;
			while(!s.empty())s.pop();
			pii l=mp(x,y);
			while(l!=mp(a,b)){s.push(l);l=pre[l.x][l.y];}
			while(!s.empty()){exch(s.top().x,s.top().y);s.pop();}
		}
		void access(int x,int y)
		{
			way_to(x,y);
			pii s=mp(x,y);
			use[x][y]=1;
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(!use[i][j] && mid[i][j]==end[x][y])s=mp(i,j);
			use[x][y]=0;
			if(s==mp(x,y)){printf("-1\n");exit(0);}
			for(;;)
			{
				way_to(s.x,s.y);
				s=ans[ans.size()-2];
				if(mp(x,y)==s)break;
				use[s.x][s.y]=1;way_to(x,y);use[s.x][s.y]=0;
			}
			use[x][y]=1;
		}
		void test(){for(int i=1;i<=n;++i,cout<<endl)for(int j=1;j<=m;++j)cout<<mid[i][j]<<' ';}
		void top_judge()
		{
			load();
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(ori[i][j]==end[n][m])a=i,b=j;
			ans.pb(mp(a,b));
			for(int i=1;i<=n-2;++i)for(int j=1;j<=m;++j)access(i,j);
			for(int i=1;i<=m-1;++i)access(n-1,i),access(n,i);
			judge();
			if(a==n-1)exch(n,m);else exch(n-1,m);
			judge();
			printf("-1\n");return;
		}
}node;

int main()
{
	//open();
	node.work();
}


#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
#define x first
#define y second
#define mp make_pair
#define pb push_back

void open()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
}

int dx[8]={-1, 0, 1,-1,0,1,-1,1};
int dy[8]={-1,-1,-1,1, 1,1,0, 0};

class chess
{
	public:
		int ori[33][33],end[33][33],mid[33][33],m,n,a,b,num[2][901];
		bool use[33][33];pii pre[33][33];
		vector<pii> ans;
		void work()
		{
			read();
			all_judge();
			pre_judge();
			if(min(n,m)==1)work1();
			top_judge();
		}
	private:
		void read()
		{
			cin>>n>>m;
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)cin>>ori[i][j];
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)cin>>end[i][j];
		}
		bool all_judge()
		{
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)++num[0][ori[i][j]],++num[1][end[i][j]];
			for(int i=1;i<=900;++i)if(num[0][i]!=num[1][i]){printf("-1\n");exit(0);}
		}
		bool pre_judge()
		{
			for(int i=1;i<=n;++i)
				for(int j=1;j<=m;++j)
					if(ori[i][j]!=end[i][j])return 0;
			printf("0\n");
			exit(0);
		}
		inline pii wr(pii x){printf("%d %d\n",x.x,x.y);return x;}
		inline void print(){printf("%d\n",ans.size()-1);for(int i=0;i<ans.size();++i)wr(ans[i]);exit(0);}
		inline bool judge(){for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(mid[i][j]!=end[i][j])return 0;print();}
		//inline void save(){for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)mid[i][j]=ori[i][j];}
		inline void load(){ans.clear();for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)mid[i][j]=ori[i][j];}
		inline bool in(int x,int y){return 1<=x && x<=n && 1<=y && y<=m && !use[x][y];}
		inline void exch(int x,int y)
		{
			swap(mid[ans.back().x][ans.back().y],mid[x][y]);
			ans.pb(mp(x,y));a=x;b=y;
		}
		void work1()
		{
			for(int i=1;i<=max(m,n);++i)
				for(int d=-1;d<2;d+=2)
				{
					load();ans.pb(mp(n==1 ? 1 : i,n==1 ? i : 1));
					for(int k=1;1<=k && k<=max(m,n);k+=d)
					{
						exch(n==1 ? 1 : k,n==1 ? k : 1);
						judge();
					}
				}
				printf("-1\n");exit(0);
		}
		void way_to(int x,int y)
		{
			//cout<<x<<" "<<y<<endl;
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)pre[i][j]=mp(-1,-1);
			queue<pii> q;pii u;
			while(!q.empty())q.pop();
			q.push(mp(a,b));
			while(!q.empty())
			{
				u=q.front();q.pop();
				for(int d=0;d<8;++d)
					if(in(u.x+dx[d],u.y+dy[d]) && pre[u.x+dx[d]][u.y+dy[d]]==mp(-1,-1))
					{
						pre[u.x+dx[d]][u.y+dy[d]]=u;
						q.push(mp(u.x+dx[d],u.y+dy[d]));
					}
			}
			stack<pii> s;
			while(!s.empty())s.pop();
			pii l=mp(x,y);
			while(l!=mp(a,b)){s.push(l);l=pre[l.x][l.y];}
			while(!s.empty()){exch(s.top().x,s.top().y);s.pop();}
		}
		void access(int x,int y)
		{
			way_to(x,y);
			pii s=mp(x,y);
			use[x][y]=1;
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(!use[i][j] && mid[i][j]==end[x][y])s=mp(i,j);
			//wr(s);
			if(s==mp(x,y)){printf("-1\n");exit(0);}
			//cout<<"11"<<endl;
			for(;;)
			{
				way_to(s.x,s.y);
				s=ans[ans.size()-2];
				if(mp(x,y)==s)break;
				use[s.x][s.y]=1;way_to(x,y);use[s.x][s.y]=0;
			}
			use[x][y]=1;
		}
		void test()
		{
			for(int i=1;i<=n;++i,cout<<endl)for(int j=1;j<=m;++j)cout<<mid[i][j]<<' ';
		}
		void top_judge()
		{
			load();
			for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(ori[i][j]==end[n][m])a=i,b=j;
			ans.pb(mp(a,b));
			for(int i=1;i<=n-2;++i)for(int j=1;j<=m;++j)access(i,j);
			for(int i=1;i<=m-1;++i)access(n-1,i),access(n,i);
			//test();
			judge();
			if(a==n-1)access(n,m);else access(n-1,m);
			judge();
			printf("-1\n");return;
		}
}node;

int main()
{
	//open();
	node.work();
}