#include <bits/stdc++.h>

using namespace std;

const int N = 1000505, LOG = 21;

int n;
int L[N], P[N][LOG];

int cur_dia, v1, v2;

int findParent (int p, int x) {
	for (int i = LOG - 1; i >= 0; i--) {
		if (x >= (1 << i) && p != -1) {
			p = P[p][i];
			x -= (1 << i);
		}
	}

	return p;
}

int getLCA (int p, int q) {
	if (L[p] < L[q])
		swap (p, q);

	int log = 1;
	for (log = 1; (1 << log) <= L[p]; log++);
	log --;

	for (int i = log; i >= 0; i--) {
		if (L[p] - L[q] >= (1 << i)) {
			p = P[p][i];
		}
	}

	assert (L[p] == L[q]);

	if (p == q)
		return p;

	for (int i = log; i >= 0; i--) {
		if (P[p][i] != -1 && P[p][i] != P[q][i]) {
			assert (L[p] == L[q]);
			p = P[p][i];
			q = P[q][i];
		}
	}

	return P[p][0];
}

int getDist (int u, int v) {
	int lca = getLCA (u, v);
	if (lca <= 0)
		lca = 0;

	//printf ("lca %d\n", lca);

	return L[u] + L[v] - 2 * L[lca];
}

void add (int u, int par) {
	L[u] = L[par] + 1;
	P[u][0] = par;

	for (int len = 1; len < LOG; len++) {
		P[u][len] = findParent (par, (1 << len) - 1);
	}

	int d1 = getDist (v1, u);
	int d2 = getDist (v2, u);

	//printf ("Dist %d, %d %d , %d %d\n", u, v1, v2, d1, d2);

	if (max (d1, d2) > cur_dia) {
		if (d1 > d2) {
			cur_dia = d1;
			v2 = u;
		} else {
			cur_dia = d2;
			v1 = u;
		}
	}
}

int main() {
	int T = 1;
	while (T--) {
		scanf ("%d", &n);

		cur_dia = 0;
		v1 = 0, v2 = 0;
		memset (P, -1, sizeof (P));
		memset (L, 0, sizeof (L));

		for (int i = 0; i < 3; i++) {
			int t = 1;
			t --;

			if (i == 0) {
				L[i + 1] = 1;
				P[i + 1][0] = 0;
				cur_dia = 1;
				v1 = 0;
				v2 = 1;
			} else {
				add (i + 1, t);
			}

			//printf ("Ans %d\n", cur_dia);
		}

        vector <int> value;
        for (int i = 0; i < n; i++) {
            int t;
            scanf ("%d", &t);
            t --;
            value.push_back (t);
        }

        int cnt = 0;
		for (int i = 3; i + 1 < 2 * (n + 2); i++) {
			int t = value[cnt / 2];

			if (i == 0) {
				L[i + 1] = 1;
				P[i + 1][0] = 0;
				cur_dia = 1;
				v1 = 0;
				v2 = 1;
			} else {
				add (i + 1, t);
			}

            if (cnt % 2 == 0)
                printf ("%d\n", cur_dia);
            cnt ++;
		}
	}

	return 0;
}


//by david942j
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#include <cassert>
#include <stack>
#define PAUSE fgetc(stdin);
#include <string>
#include <cmath>
#include <algorithm>
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define __count(x) __builtin_popcount(x)
#define RI(x) scanf("%d",&x)
#define RI2(a,b) scanf("%d%d",&a,&b)
#define RI3(a,b,c) scanf("%d%d%d",&a,&b,&c)
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
const int N=40, lgN=20;
const int INF=2000000000;
int n,m,*A[N],*B[N];
bool fail;
bool rev;
vector<PII> ans;

int *bA[N];
void print(int **A,int n,int m) {
    FOR(i,n)FOR(j,m)printf("%d%c",A[i][j],j==m-1?'\n':' ');
}
int **reflex(int n,int m,int **A) {
    int **B=new int*[m];
    FOR(i,m)B[i]=new int[n];
    FOR(i,n)FOR(j,m)B[j][i]=A[i][j];
    return B;
}
bool same(int **A,int **B,int n,int m) {
    FOR(i,n)FOR(j,m)if(A[i][j]!=B[i][j])return false;
    return true;
}
void find_c(int n,int m,int p,int **A,int c,int &x,int &y) {
    FOR(j,m)FOR(i,n)
    if(i+j==0)continue;
    else if(j==m-1 && i>=p)return;
    else if(A[i][j]==c) {
        x=i;y=j;
        return;
    }
}
enum {
    UP=0,
    DOWN=1,
    LEFT=2,
    RIGHT=3,
    RU=4,
    RD=5,
    LD=6,
    LU=7
};
int dx[]={-1,1,0,0,-1,1,1,-1},dy[]={0,0,-1,1,1,1,-1,-1};
void udlr(int **A,int &x,int &y,int d) {
    swap(A[x][y],A[x+dx[d]][y+dy[d]]);
    x+=dx[d];y+=dy[d];
    if(rev)ans.pb(mpr(y,x));
    else ans.pb(mpr(x,y));
}
void d_move(int **A,int &x,int &y,int a,int b) {
    while(x!=a || y!=b) {
        if(x>a)udlr(A,x,y,0);
        else if(x<a)udlr(A,x,y,1);
        else if(y>b)udlr(A,x,y,2);
        else if(y<b)udlr(A,x,y,3);
    }
}

void make_up(int **A,int &x,int &y) {
    udlr(A,x,y,DOWN);
    if(x==1)return;
    if(y>0) {
        udlr(A,x,y,LU);
        udlr(A,x,y,RU);
        make_up(A,x,y);
    }
    else {
        udlr(A,x,y,RU);
        udlr(A,x,y,LU);
        make_up(A,x,y);
    }
}
void make_right(int **A,int &x,int &y,int m) {
    udlr(A,x,y,RU);
    udlr(A,x,y,LEFT);
    if(y==m-2)return;
    udlr(A,x,y,RD);
    make_right(A,x,y,m);
}
void make_down(int **A,int &x,int &y,int n) {
    udlr(A,x,y,RD);
    udlr(A,x,y,UP);
    if(x==n-2)return;
    udlr(A,x,y,LD);
    make_down(A,x,y,n);
}
void just_go(int x,int a,int **A) {
    if(x==a)return;
    if(x<a) {
        for(int i=x+1;i<=a;i++)
            swap(A[0][i],A[0][i-1]);
    }
    else {
        for(int i=x-1;i>=a;i--)
            swap(A[0][i],A[0][i+1]);
    }
}
void solve1(int n,int m,int **A,int **B) {
    if(n>m) {
        int **C,**D;
        C=reflex(n,m,A);
        D=reflex(n,m,B);
        rev^=1;
        return solve1(m,n,C,D);
    }
    FOR(i,m)FOR(j,m) {
        just_go(i,j,A);
        if(same(A,B,1,m)) {
            int x=0,y=i;
            if(rev)ans.pb(mpr(y,x));
            else ans.pb(mpr(x,y));
            d_move(A,x,y,0,j);
            return;
        }
        just_go(j,i,A);
    }
    fail=true;
}
void solve22(int **A,int **B) {
    int x=0,y=0;
    int step=0;
    while(true) {
        if(same(A,B,2,2))return;
        if(step>1000){fail=true;return;}
        while(true) {
            int r=rand()%8;
            int a=x+dx[r],b=y+dy[r];
            if(a<0||a>=2||b<0||b>=2)continue;
            udlr(A,x,y,r);
            step++;
            break;
        }
    }
}
void solve(int n,int m,int **A,int **B) {
    if(n>m) {
        int **C,**D;
        C=reflex(n,m,A);
        D=reflex(n,m,B);
        rev^=1;
        return solve(m,n,C,D);
    }
    if(n==2 && m==2)
        return solve22(A,B);
    for(int i=n-1;i>=0;i--) {
        int x=-1,y=-1;
        if(A[i][m-1]==B[i][m-1])continue;
        find_c(n,m,i,A,B[i][m-1],x,y);
        if(x==-1){fail=true;return;}
        int nowx=0,nowy=0;
        if(x==0) {
            d_move(A,nowx,nowy,x,y-1);
            udlr(A,nowx,nowy,RD);
        }
        else {
            d_move(A,nowx,nowy,x-1,y);
            make_up(A,nowx,nowy); //make nowx+1,nowy to top
        }
        if(nowy==m-1)
            udlr(A,nowx,nowy,LU);
        else make_right(A,nowx,nowy,m); //make nowx-1,nowy to rightest
        if(nowx==i)d_move(A,nowx,nowy,0,0);//back
        else {
            make_down(A,nowx,nowy,i+1);//make nowx,nowy+1 to i,nowy+1
            d_move(A,nowx,nowy,0,0);//back
        }
    }
    solve(n,m-1,A,B);
}
int main() {
    FOR(i,N)A[i]=new int [N],bA[i]=new int [N];
    FOR(i,N)B[i]=new int [N];
    RI2(n,m);
    FOR(i,n)FOR(j,m)RI(A[i][j]),bA[i][j]=A[i][j];
    FOR(i,n)FOR(j,m)RI(B[i][j]);
    if(min(n,m)==1) solve1(n,m,A,B);
    else {
        if(A[0][0]!=B[0][0]) {
            int x=-1,y;
            find_c(n,m,N,A,B[0][0],x,y);
            if(x==-1){puts("-1");return 0;}
            ans.pb(mpr(x,y));
            d_move(A,x,y,0,0);
        }
        else ans.pb(mpr(0,0));
        solve(n,m,A,B);
    }
    if(fail)puts("-1");
    else {
        printf("%d\n",ans.size()-1);
        FOR(i,ans.size())
            printf("%d %d\n",ans[i].X+1,ans[i].Y+1);
    }
    /*FOR1(i,(int)ans.size()-1) {
        swap(bA[ans[i-1].X][ans[i-1].Y],bA[ans[i].X][ans[i].Y]);
    }*/
    //print(bA,n,m);
}
/*

  2 6
  1 2 3 4 5 6
  7 8 9 1 2 3

  1 6 5 4 3 2
  3 7 8 1 2 9

  3 3
  1 3 9
  2 4 1
  6 7 2

  4 7 6
  2 9 3
  1 1 2

  2 2
  1 3
  2 3
  1 3
  3 2

  2 2
  1 3
  2 3
  1 2
  2 3

  1 4
  1 2 3 4
  4 3 2 1

  4 1
  1
  2
  3
  4
  3
  1
  2
  4

 */
// ntuj - dnmgsokxu7n9ghce5uerf


#include <bits/stdc++.h>
using namespace std;
#define N 40
#define K 910
int getint(){
    int x=0; char c=getchar();
    while( c<'0'||c>'9' ) c=getchar();
    while(c>='0'&&c<='9') x*=10,x+=(c-'0'),c=getchar();
    return x;
}
vector< pair<int,int> > ans;
int n , m , tag;
int a[ N ][ N ] , b[ N ][ N ] , cnt[ K ];
void init(){
    n = getint(); m = getint();
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ ){
            a[ i ][ j ] = getint();
            cnt[ a[ i ][ j ] ] ++;
            if( cnt[ a[ i ][ j ] ] == 1 ) tag ++;
        }
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ ){
            b[ i ][ j ] = getint();
            cnt[ b[ i ][ j ] ] --;
            if( cnt[ b[ i ][ j ] ] == 0 ) tag --;
            if( cnt[ b[ i ][ j ] ] < 0 ) tag = 10000;
        }
}
void solve2(){
    if( n == 1 ){
        for( int i = 1 ; i <= m ; i++ )
            if( a[ 1 ][ i ] != b[ 1 ][ i ] ){
                for( int j = i + 1 ; j <= m ; j ++ ){
                    if( a[ 1 ][ j ] != b[ 1 ][ i ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k < j ; k ++ )
                        if( a[ 1 ][ k ] != b[ 1 ][ k + 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j + 1 ; k <= m ; k ++ )
                        if( a[ 1 ][ k ] != b[ 1 ][ k ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , j - i );
                        for( int k = j ; k >= i ; k -- )
                            printf( "1 %d\n" , k );
                        return;
                    }
                }
                break;
            }
        for( int i = m ; i >= 1 ; i -- )
            if( a[ 1 ][ i ] != b[ 1 ][ i ] ){
                for( int j = i - 1 ; j >= 1 ; j -- ){
                    if( a[ 1 ][ j ] != b[ 1 ][ i ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k > j ; k -- )
                        if( a[ 1 ][ k ] != b[ 1 ][ k - 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j - 1 ; k >= 1 ; k -- )
                        if( a[ 1 ][ k ] != b[ 1 ][ k ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , i - j );
                        for( int k = j ; k <= i ; k ++ )
                            printf( "1 %d\n" , k );
                        return;
                    }
                }
                break;
            }
        puts( "-1" );
        return;
    }else{
        for( int i = 1 ; i <= n ; i++ )
            if( a[ i ][ 1 ] != b[ i ][ 1 ] ){
                for( int j = i + 1 ; j <= n ; j ++ ){
                    if( a[ j ][ 1 ] != b[ i ][ 1 ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k < j ; k ++ )
                        if( a[ k ][ 1 ] != b[ k + 1 ][ 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j + 1 ; k <= n ; k ++ )
                        if( a[ k ][ 1 ] != b[ k ][ 1 ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , j - i );
                        for( int k = j ; k >= i ; k -- )
                            printf( "%d 1\n" , k );
                        return;
                    }
                }
            }
        for( int i = n ; i >= 1 ; i -- )
            if( a[ i ][ 1 ] != b[ i ][ 1 ] ){
                for( int j = i - 1 ; j >= 1 ; j -- ){
                    if( a[ j ][ 1 ] != b[ i ][ 1 ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k > j ; k -- )
                        if( a[ k ][ 1 ] != b[ k - 1 ][ 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j - 1 ; k >= 1 ; k -- )
                        if( a[ k ][ 1 ] != b[ k ][ 1 ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , i - j );
                        for( int k = j ; k <= i ; k ++ )
                            printf( "%d 1\n" , k );
                        return;
                    }
                }
                break;
            }
        puts( "-1" );
        return;
    }
}
int sn , sm;
void move( int ttn , int ttm ){
    while( sn != ttn && sm != ttm ){
        if( sn > ttn && sm > ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm - 1 ];
            a[ sn - 1 ][ sm - 1 ] = tswap;
            sn --; sm --;
        }else if( sn > ttn && sm < ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm + 1 ];
            a[ sn - 1 ][ sm + 1 ] = tswap;
            sn --; sm ++;
        }else if( sn < ttn && sm > ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm - 1 ];
            a[ sn + 1 ][ sm - 1 ] = tswap;
            sn ++; sm --;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm + 1 ];
            a[ sn + 1 ][ sm + 1 ] = tswap;
            sn ++; sm ++;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
    while( sn != ttn ){
        if( sn < ttn ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm ];
            a[ sn + 1 ][ sm ] = tswap;
            sn ++;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm ];
            a[ sn - 1 ][ sm ] = tswap;
            sn --;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
    while( sm != ttm ){
        if( sm < ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn ][ sm + 1 ];
            a[ sn ][ sm + 1 ] = tswap;
            sm ++;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn ][ sm - 1 ];
            a[ sn ][ sm - 1 ] = tswap;
            sm --;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
}
void turn( int rn ){
    for( int i = m ; i >= 1 ; i -- ){
        move( 1 , 1 );
        if( a[ rn ][ i ] == b[ rn ][ i ] )
            continue;
        int xn = 0 , xm;
        for( int j = rn ; j >= 1 ; j -- ){
            for( int k = (j == rn ? i-1 :m) ; k >= 1 ; k -- )if( a[ j ][ k ] == b[ rn ][ i ] ){
                xn = j; xm = k; break;
            }
            if( xn ) break;
        }
        if( xm > i && xn < rn ){
            while( xm > i && xn < rn && xm - i > rn - xn ){
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }else{
                    move( xn - 1 , xm );
                    move( xn , xm - 1 );
                    move( xn , xm );
                    xm --;
                }
            }
        }
        while( xn != rn && xm != i ){
            if( xm < i ){
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }else{
                    move( xn - 1 , xm + 1 );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }
            }else{
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }else{
                    move( xn - 1 , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }
            }
        }
        while( xn != rn ){
            if( xn == 1 ){
                move( xn , xm - 1 );
                move( xn + 1 , xm );
                move( xn , xm );
                xn ++;
            }else{
                move( xn - 1 , xm );
                if( xm == 1 ) move( xn , xm + 1 );
                else move( xn , xm - 1 );
                move( xn + 1 , xm );
                move( xn , xm );
                xn ++;
            }
        }
        while( xm != i ){
assert( xn - 1 >= 1 && xm + 1 <= m );
            move( xn - 1 , xm );
            move( xn , xm + 1 );
            move( xn , xm );
            xm ++;
        }
    }
}
void turn2(){
    for( int j = m ; j >= 1 ; j -- )
        for( int i = 2 ; i >= 1 ; i -- ){
            move( 1 , 1 );
            if( a[ i ][ j ] == b[ i ][ j ] )
                continue;
            int xn = 0 , xm;
            for( int k = j ; k >= 1 ; k -- ){
                for( int l = (k==j? i - 1 : 2) ; l >= 1 ; l -- ){
                    if( a[ l ][ k ] == b[ i ][ j ] ){
                        xn = l; xm = k; break;
                    }
                }
                if( xn ) break;
            }
            while( xn != i && xm != j ){
                if( xn < i ){
                    move( xn + 1 , xm - 1 );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }else{
                    move( xn - 1 , xm + 1 );
                    move( xn , xm );
                    xn --; xm ++;
                }
            }
            while( xn != i ){
                if( xn < i ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn , xm );
                    xn ++;
                }else{
                    move( xn - 1 , xm );
                    move( xn , xm );
                    xn --;
                }
            }
            while( xm != j ){
                if( xn != 1 ){
                    move( xn - 1 , xm );
                    move( xn , xm + 1 );
                    move( xn , xm );
                    xm ++;
                }else{
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn , xm + 1 );
                    move( xn , xm );
                    xm ++;
                }
            }
        }
}
void solve3(){
    for( int i = 1 ; i <= n ; i ++ ){
        for( int j = 1 ; j <= m ; j ++ )
            if( a[ i ][ j ] == b[ 1 ][ 1 ] ){
                sn = i; sm = j;
                break;
            }
        if( sn ) break;
    }
    int an = sn , am = sm;
    move( 1 , 1 );
//    printf( "%d %d\n" , sn , sm );
    for( int i = n ; i > 2 ; i -- )
        turn( i );
    turn2();
    printf( "%d\n" , (int)ans.size() );
    printf( "%d %d\n" , an , am );
    for( int i = 0 ; i < (int)ans.size() ; i ++ )
        printf( "%d %d\n" , ans[ i ].first , ans[ i ].second );
}
void solve(){
    if( tag != 0 ){
        puts( "-1" );
        return;
    }
    if( n == 1 || m == 1 ) solve2();
    else solve3();
}
int main(){
    init();
    solve();
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <queue>
#include <cstdlib>

using namespace std;

int N, M;
bool bad[35][35];

pair<int, int> A[35][35];
pair<int, int> B[35][35];

int dr[] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dc[] = {-1, 0, 1, 1, 1, 0, -1, -1};

vector<pair<int, int> > R;

void domove(int r, int c) {
  int mr = B[0][0].first;
  int mc = B[0][0].second;
  swap(B[0][0], B[A[r][c].first][A[r][c].second]);
  swap(A[mr][mc], A[r][c]);
  R.push_back(make_pair(r, c));
}

void path(int tr, int tc, int xr, int xc) {
  bad[xr][xc] = true;

  queue<int> q;
  q.push(tr * M + tc);
  vector<int> dd(M * N, -1);
  dd[tr * M + tc] = 0;
  while(!q.empty()) {
    int u = q.front();
    int ur = u / M;
    int uc = u % M;
    q.pop();
    for(int i = 0; i < 8; i++) {
      int vr = ur + dr[i];
      int vc = uc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if (dd[v] == -1) {
        dd[v] = dd[u] + 1;
        q.push(v);
      }
    }
  }

  int& mr = B[0][0].first;
  int& mc = B[0][0].second;
  while(mr != tr && mc != tc) {
    int m = mr * M + mc;
    for(int i = 0; i < 8; i++) {
      int vr = mr + dr[i];
      int vc = mc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if(dd[v] + 1 == dd[m]) {
        domove(vr, vc);
        break;
      }
    }
  }

  bad[xr][xc] = false;
}

void move(int tr, int tc) {
  int& pr = B[tr][tc].first;
  int& pc = B[tr][tc].second;
  while(pr > tr) {
    path(pr - 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc > tc) {
    path(pr, pc - 1, pr, pc);
    domove(pr, pc);
  }
  while(pr < tr) {
    path(pr + 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc < tc) {
    path(pr, pc + 1, pr, pc);
    domove(pr, pc);
  }
}

int main() {
  cin >> N >> M;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> A[i][j].first;
    }
  }
  map<int, vector<pair<int, int> > > mp;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> B[i][j].first;
      mp[B[i][j].first].push_back(make_pair(i, j));
    }
  }

  if (N == 1 || M == 1) {
    vector<int> V1, V2;
    for(int i = 0; i < N; i++) {
      for(int j = 0; j < M; j++) {
        V1.push_back(A[i][j].first);
        V2.push_back(B[i][j].first);
      }
    }
    if (V1 == V2) {
      cout << "0\n1 1\n";
      return 0;
    }
    for(int i = 0; i + 1 < V1.size(); i++) {
      vector<int> NV = V1;
      for(int j = i + 1; j < V1.size(); j++) {
        swap(NV[j - 1], NV[j]);
        if (NV == V2) {
          cout << j - i << "\n";
          for(int k = i; k <= j; k++) {
            if(N == 1) {
              cout << 1 << " " << k + 1 << "\n";
            } else {
              cout << k + 1 << " 1\n";
            }
          }
          return 0;
        }
      }
      NV = V1;
      for(int j = i - 1; j >= 0; j--) {
        swap(NV[j + 1], NV[j]);
        if (NV == V2) {
          cout << i - j << "\n";
          for(int k = i; k >= j; k--) {
            if(N == 1) {
              cout << 1 << " " << k + 1 << "\n";
            } else {
              cout << k + 1 << " 1\n";
            }
          }
          return 0;
        }
      }
    }
    cout << "-1\n";
    return 0;
  }

  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      vector<pair<int, int> >& V = mp[A[i][j].first];
      if (V.empty()) {
        cout << "-1\n";
        return 0;
      }
      A[i][j] = V.back();
      B[A[i][j].first][A[i][j].second] = make_pair(i, j);
      V.resize(V.size() - 1);
    }
  }

  R.push_back(B[0][0]);
  while(N && M) {
    if (N > M) {
      for(int i = M - 1; i >= 0; i--) {
        move(N - 1, i);
        bad[N - 1][i] = true;
      }
      N--;
    } else {
      for(int i = N - 1; i >= 0; i--) {
        move(i, M - 1);
        bad[i][M - 1] = true;
      }
      M--;
    }
  }

  cout << R.size() - 1 << "\n";
  for(int i = 0; i < R.size(); i++) {
    cout << R[i].first + 1 << ' ' << R[i].second + 1 << "\n";
  }

  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <queue>
#include <cstdlib>

using namespace std;

int N, M;
bool bad[35][35];

pair<int, int> A[35][35];
pair<int, int> B[35][35];

int dr[] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dc[] = {-1, 0, 1, 1, 1, 0, -1, -1};

vector<pair<int, int> > R;

void domove(int r, int c) {
  int mr = B[0][0].first;
  int mc = B[0][0].second;
  swap(B[0][0], B[A[r][c].first][A[r][c].second]);
  swap(A[mr][mc], A[r][c]);
  R.push_back(make_pair(r, c));
}

void path(int tr, int tc, int xr, int xc) {
  bad[xr][xc] = true;

  queue<int> q;
  q.push(tr * M + tc);
  vector<int> dd(M * N, -1);
  dd[tr * M + tc] = 0;
  while(!q.empty()) {
    int u = q.front();
    int ur = u / M;
    int uc = u % M;
    q.pop();
    for(int i = 0; i < 8; i++) {
      int vr = ur + dr[i];
      int vc = uc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if (dd[v] == -1) {
        dd[v] = dd[u] + 1;
        q.push(v);
      }
    }
  }

  int& mr = B[0][0].first;
  int& mc = B[0][0].second;
  while(mr != tr && mc != tc) {
    int m = mr * M + mc;
    for(int i = 0; i < 8; i++) {
      int vr = mr + dr[i];
      int vc = mc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if(dd[v] + 1 == dd[m]) {
        domove(vr, vc);
        break;
      }
    }
  }

  bad[xr][xc] = false;
}

void move(int tr, int tc) {
  int& pr = B[tr][tc].first;
  int& pc = B[tr][tc].second;
  while(pr > tr) {
    path(pr - 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc > tc) {
    path(pr, pc - 1, pr, pc);
    domove(pr, pc);
  }
  while(pr < tr) {
    path(pr + 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc < tc) {
    path(pr, pc + 1, pr, pc);
    domove(pr, pc);
  }
}

int main() {
  cin >> N >> M;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> A[i][j].first;
    }
  }
  map<int, vector<pair<int, int> > > mp;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> B[i][j].first;
      mp[B[i][j].first].push_back(make_pair(i, j));
    }
  }

  if (N == 1 || M == 1) {
    vector<int> V1, V2;
    for(int i = 0; i < N; i++) {
      for(int j = 0; j < M; j++) {
        V1.push_back(A[i][j].first);
        V2.push_back(B[i][j].first);
      }
    }
    for(int i = 0; i < V1.size(); i++) {
      for(int j = i; j <= V1.size(); j++) {
        rotate(V1.begin() + i, V1.begin() + i + 1, V1.begin() + j);
        if (V1 == V2) {
          cout << j - i << "\n";
          for(int k = i; k < j; k++) {
            if(N == 1) {
              cout << 1 << " " << k + 1 << "\n";
            } else {
              cout << k + 1 << " 1\n";
            }
          }
          return 0;
        }
        rotate(V1.begin() + i, V1.begin() + j - 1, V1.begin() + j);
      }
      for(int j = i; j <= V1.size(); j++) {
        rotate(V1.begin() + i, V1.begin() + j - 1, V1.begin() + j);
        if (V1 == V2) {
          cout << j - i << "\n";
          for(int k = j; k > i; k--) {
            if(N == 1) {
              cout << 1 << " " << k << "\n";
            } else {
              cout << k << " 1\n";
            }
          }
          return 0;
        }
        rotate(V1.begin() + i, V1.begin() + i + 1, V1.begin() + j);
      }
    }
    cout << "-1\n";
    return 0;
  }

  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      vector<pair<int, int> >& V = mp[A[i][j].first];
      if (V.empty()) {
        cout << "-1\n";
        return 0;
      }
      A[i][j] = V.back();
      B[A[i][j].first][A[i][j].second] = make_pair(i, j);
      V.resize(V.size() - 1);
    }
  }

  R.push_back(B[0][0]);
  while(N && M) {
    if (N > M) {
      for(int i = M - 1; i >= 0; i--) {
        move(N - 1, i);
        bad[N - 1][i] = true;
      }
      N--;
    } else {
      for(int i = N - 1; i >= 0; i--) {
        move(i, M - 1);
        bad[i][M - 1] = true;
      }
      M--;
    }
  }

  cout << R.size() << "\n";
  for(int i = 0; i < R.size(); i++) {
    cout << R[i].first + 1 << ' ' << R[i].second + 1 << "\n";
  }

  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <queue>
#include <cstdlib>

using namespace std;

int N, M;
bool bad[35][35];

pair<int, int> A[35][35];
pair<int, int> B[35][35];

int dr[] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dc[] = {-1, 0, 1, 1, 1, 0, -1, -1};

vector<pair<int, int> > R;

void domove(int r, int c) {
  int mr = B[0][0].first;
  int mc = B[0][0].second;
  swap(B[0][0], B[A[r][c].first][A[r][c].second]);
  swap(A[mr][mc], A[r][c]);
  R.push_back(make_pair(r, c));
}

void path(int tr, int tc, int xr, int xc) {
  bad[xr][xc] = true;

  queue<int> q;
  q.push(tr * M + tc);
  vector<int> dd(M * N, -1);
  dd[tr * M + tc] = 0;
  while(!q.empty()) {
    int u = q.front();
    int ur = u / M;
    int uc = u % M;
    q.pop();
    for(int i = 0; i < 8; i++) {
      int vr = ur + dr[i];
      int vc = uc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if (dd[v] == -1) {
        dd[v] = dd[u] + 1;
        q.push(v);
      }
    }
  }

  int& mr = B[0][0].first;
  int& mc = B[0][0].second;
  while(mr != tr || mc != tc) {
    int m = mr * M + mc;
    for(int i = 0; i < 8; i++) {
      int vr = mr + dr[i];
      int vc = mc + dc[i];
      int v = vr * M + vc;
      if (vr < 0 || vr >= N || vc < 0 || vc >= M || bad[vr][vc]) continue;
      if(dd[v] + 1 == dd[m]) {
        domove(vr, vc);
        break;
      }
    }
  }

  bad[xr][xc] = false;
}

void move(int tr, int tc) {
  int& pr = B[tr][tc].first;
  int& pc = B[tr][tc].second;
  while(pr > tr) {
    path(pr - 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc > tc) {
    path(pr, pc - 1, pr, pc);
    domove(pr, pc);
  }
  while(pr < tr) {
    path(pr + 1, pc, pr, pc);
    domove(pr, pc);
  }
  while(pc < tc) {
    path(pr, pc + 1, pr, pc);
    domove(pr, pc);
  }
}

int main() {
  cin >> N >> M;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> A[i][j].first;
      //A[i][j].first = i * M + j;
    }
  }
  map<int, vector<pair<int, int> > > mp;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      cin >> B[i][j].first;
      //B[i][j].first = j * N + i;
      mp[B[i][j].first].push_back(make_pair(i, j));
    }
  }

  if (N == 1 || M == 1) {
    vector<int> V1, V2;
    for(int i = 0; i < N; i++) {
      for(int j = 0; j < M; j++) {
        V1.push_back(A[i][j].first);
        V2.push_back(B[i][j].first);
      }
    }
    if (V1 == V2) {
      cout << "0\n1 1\n";
      return 0;
    }
    for(int i = 0; i + 1 < V1.size(); i++) {
      vector<int> NV = V1;
      for(int j = i + 1; j < V1.size(); j++) {
        swap(NV[j - 1], NV[j]);
        if (NV == V2) {
          cout << j - i << "\n";
          for(int k = i; k <= j; k++) {
            if(N == 1) {
              cout << 1 << " " << k + 1 << "\n";
            } else {
              cout << k + 1 << " 1\n";
            }
          }
          return 0;
        }
      }
      NV = V1;
      for(int j = i - 1; j >= 0; j--) {
        swap(NV[j + 1], NV[j]);
        if (NV == V2) {
          cout << i - j << "\n";
          for(int k = i; k >= j; k--) {
            if(N == 1) {
              cout << 1 << " " << k + 1 << "\n";
            } else {
              cout << k + 1 << " 1\n";
            }
          }
          return 0;
        }
      }
    }
    cout << "-1\n";
    return 0;
  }

  for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
      vector<pair<int, int> >& V = mp[A[i][j].first];
      if (V.empty()) {
        cout << "-1\n";
        return 0;
      }
      A[i][j] = V.back();
      B[A[i][j].first][A[i][j].second] = make_pair(i, j);
      V.resize(V.size() - 1);
    }
  }

  R.push_back(B[0][0]);
  while(N && M) {
    if (N > M) {
      for(int i = M - 1; i >= 0; i--) {
        move(N - 1, i);
        bad[N - 1][i] = true;
      }
      N--;
    } else {
      for(int i = N - 1; i >= 0; i--) {
        move(i, M - 1);
        bad[i][M - 1] = true;
      }
      M--;
    }
  }

  cout << R.size() - 1 << "\n";
  for(int i = 0; i < R.size(); i++) {
    cout << R[i].first + 1 << ' ' << R[i].second + 1 << "\n";
  }

  return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>

using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); ++e)
typedef long long LL;
typedef pair<int, int> PII;

int n, m;
int s[31][31], t[31][31], tmp[31];
int cnt[901] = {};
vector<PII> ans;
int posi, posj;

inline void go(int di, int dj) {
    ans.pb(mp(posi + di, posj + dj));
    swap(s[posi][posj], s[posi + di][posj + dj]);
    posi += di;
    posj += dj;
}

void solve(int sti, int stj) {
    ans.pb(mp(sti, stj));
    posi = sti, posj = stj;
    if (posi == 1) go(1, 0);
    if (posj == 1) go(0, 1);
    for (int i = n; i >= 3; --i) for (int j = m; j >= 1; --j) {
        int ii = i, jj = j;
        while (s[ii][jj] != t[i][j] || (ii == posi && jj == posj)) {
            --jj;
            if (jj == 0) jj = m, --ii;
        }
        if (ii == i && jj == j) continue;
        if (posj == jj) {
            if (posj == 1) go(-1, 1);
            else go(-1, -1);
        }
        while (posi < ii) go(1, 0);
        while (posi > ii) go(-1, 0);
        while (posj < jj - 1) go(0, 1);
        while (posj > jj + 1) go(0, -1);
        if (posi == 1) {
            go(1, jj - posj);
            go(-1, 0); ++ii;
            if (posj == 1) go(1, 1);
            else go(1, -1);
        }
        if (posj > jj && jj > 1) {
            go(-1, -1);
            go(1, -1);
        }
        while (jj > 2) {
            go(0, 1);
            --jj;
            go(-1, -1);
            go(1, -1);
        }
        if (jj == 2) {
            go(0, 1);
            --jj;
        }
        while (ii < i) {
            go(1, -1);
            go(-1, 0); ++ii;
            if (ii != i || jj != j) {
                go(1, 1);
            }
        }
        while (jj < j) {
            go(0, -1); ++jj;
            if (jj != j) {
                go(-1, 1);
                go(1, 1);
            }
        }
    }
    for (int j = m; j >= 3; --j) for (int i = 1; i <= 2; ++i) {
        while (posj >= j) go(0, -1);
        if (s[i][j] == t[i][j]) continue;
        if (s[3 - i][j] == t[i][j] && i == 1) {
            if (abs(posj - j) <= 1) {
                go(1 - posi, j - posj);
                go(1, 0);
                continue;
            }
            if (posi == 2) go(-1, 0);
            while (posj < j) go(0, 1);
            while (posj > j) go(0, -1);
            go(1, 0);
            continue;
        }
        int ii = i, jj = j;
        while (s[ii][jj] != t[i][j] || (ii == posi && jj == posj)) {
            ++ii;
            if (ii == 3) ii = 1, --jj;
        }
        if (ii == posi) {
            if (posi == 2) go(-1, 0);
            else go(1, 0);
        }
        while (posj < jj) go(0, 1);
        while (posj > jj) go(0, -1);
        if (ii != i) {
            go(ii - posi, 0);
            ii = 3 - ii;
        }
        if (jj == j) continue;
        go(ii - posi, 1);
        if (posi == 1) {
            go(0, -1); ++jj;
            while (jj < j) {
                go(1, 1);
                go(-1, 1);
                go(0, -1); ++jj;
            }
        } else {
            go(0, -1); ++jj;
            while (jj < j) {
                go(-1, 1);
                go(1, 1);
                go(0, -1); ++jj;
            }
        }
    }
    while (posi > 1) go(-1, 0);
    while (posj > 1) go(0, -1);
    if (s[1][2] != t[1][2]) {
        go(0, 1);
        if (s[2][1] == t[1][2]) go(1, -1), go(-1, 0);
        else go(1, 0), go(-1, -1);
    }
    if (s[2][1] != t[2][1]) {
        go(1, 0);
        go(0, 1);
        go(-1, -1);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) {
        scanf("%d", s[i] + j);
        ++cnt[s[i][j]];
    }
    for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) {
        scanf("%d", t[i] + j);
        --cnt[t[i][j]];
    }
    for (int i = 1; i <= 900; ++i) if (cnt[i] != 0) {
        printf("-1\n");
        return 0;
    }
    if (n == 1) {
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j < i; ++j) {
                for (int k = 1; k <= m; ++k) tmp[k] = s[1][k];
                for (int k = i - 1; k >= j; --k)
                    swap(tmp[k], tmp[k + 1]);
                bool flag = true;
                for (int k = 1; k <= m; ++k) if (tmp[k] != t[1][k]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << i - j << '\n';
                    cout << 1 << ' ' << i << '\n';
                    for (int k = i - 1; k >= j; --k)
                        cout << 1 << ' ' << k << '\n';
                    return 0;
                }
            }
            for (int j = i + 1; j <= m; ++j) {
                for (int k = 1; k <= m; ++k) tmp[k] = s[1][k];
                for (int k = i + 1; k <= j; ++k)
                    swap(tmp[k], tmp[k - 1]);
                bool flag = true;
                for (int k = 1; k <= m; ++k) if (tmp[k] != t[1][k]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << j - i << '\n';
                    cout << 1 << ' ' << i << '\n';
                    for (int k = i + 1; k <= j; ++k)
                        cout << 1 << ' ' << k << '\n';
                    return 0;
                }
            }
        }
        cout << "-1\n";
        return 0;
    }
    if (m == 1) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j < i; ++j) {
                for (int k = 1; k <= n; ++k) tmp[k] = s[k][1];
                for (int k = i - 1; k >= j; --k)
                    swap(tmp[k], tmp[k + 1]);
                bool flag = true;
                for (int k = 1; k <= n; ++k) if (tmp[k] != t[k][1]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << i - j << '\n';
                    cout << i << ' ' << 1 << '\n';
                    for (int k = i - 1; k >= j; --k)
                        cout << k << ' ' << 1 << '\n';
                    return 0;
                }
            }
            for (int j = i + 1; j <= n; ++j) {
                for (int k = 1; k <= n; ++k) tmp[k] = s[k][1];
                for (int k = i + 1; k <= j; ++k)
                    swap(tmp[k], tmp[k - 1]);
                bool flag = true;
                for (int k = 1; k <= n; ++k) if (tmp[k] != t[k][1]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << j - i << '\n';
                    cout << i << ' ' << 1 << '\n';
                    for (int k = i + 1; k <= j; ++k)
                        cout << k << ' ' << 1 << '\n';
                    return 0;
                }
            }
        }
        cout << "-1\n";
        return 0;
    }
    bool flag = true;
    for (int i = 1; i <= n; ++i) if (flag) for (int j = 1; j <= m; ++j) if (s[i][j] == t[1][1]) {
        solve(i, j);
        flag = false;
        break;
    }
    printf("%d\n", (int)ans.size() - 1);
    REP(i, ans.size()) {
        printf("%d %d\n", ans[i].first, ans[i].second);
    }
    return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>

using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); ++e)
typedef long long LL;
typedef pair<int, int> PII;

int n, m;
int s[31][31], t[31][31], tmp[31];
int cnt[901] = {};
vector<PII> ans;
int posi, posj;

inline void go(int di, int dj) {
    ans.pb(mp(posi + di, posj + dj));
    swap(s[posi][posj], s[posi + di][posj + dj]);
    posi += di;
    posj += dj;
}

void solve(int sti, int stj) {
    ans.pb(mp(sti, stj));
    posi = sti, posj = stj;
    if (posi == 1) go(1, 0);
    if (posj == 1) go(0, 1);
    for (int i = n; i >= 3; --i) for (int j = m; j >= 1; --j) {
        int ii = i, jj = j;
        while (s[ii][jj] != t[i][j] || (ii == posi && jj == posj)) {
            --jj;
            if (jj == 0) jj = m, --ii;
        }
        if (ii == i && jj == j) continue;
        if (posj == jj) {
            if (posj == 1) go(-1, 1);
            else go(-1, -1);
        }
        while (posi < ii) go(1, 0);
        while (posi > ii) go(-1, 0);
        while (posj < jj - 1) go(0, 1);
        while (posj > jj + 1) go(0, -1);
        if (posi == 1) {
            go(1, jj - posj);
            go(-1, 0); ++ii;
            if (posj == 1) go(1, 1);
            else go(1, -1);
        }
        if (posj > jj && jj > 1) {
            go(-1, -1);
            go(1, -1);
        }
        while (jj > 2) {
            go(0, 1);
            --jj;
            go(-1, -1);
            go(1, -1);
        }
        if (jj == 2) {
            go(0, 1);
            --jj;
        }
        while (ii < i) {
            go(1, -1);
            go(-1, 0); ++ii;
            if (ii != i || jj != j) {
                go(1, 1);
            }
        }
        while (jj < j) {
            go(0, -1); ++jj;
            if (jj != j) {
                go(-1, 1);
                go(1, 1);
            }
        }
    }
    for (int j = m; j >= 3; --j) for (int i = 1; i <= 2; ++i) {
        while (posj >= j) go(0, -1);
        if (s[i][j] == t[i][j]) continue;
        if (s[3 - i][j] == t[i][j] && i == 1) {
            if (abs(posj - j) <= 1) {
                go(1 - posi, j - posj);
                go(1, 0);
                continue;
            }
            if (posi == 2) go(-1, 0);
            while (posj < j) go(0, 1);
            while (posj > j) go(0, -1);
            go(1, 0);
            continue;
        }
        int ii = i, jj = j;
        while (s[ii][jj] != t[i][j] || (ii == posi && jj == posj)) {
            ++ii;
            if (ii == 3) ii = 1, --jj;
        }
        if (ii == posi) {
            if (posi == 2) go(-1, 0);
            else go(1, 0);
        }
        while (posj < jj) go(0, 1);
        while (posj > jj) go(1, 0);
        if (ii != i) {
            go(ii - posi, 0);
            ii = 3 - ii;
        }
        if (jj == j) continue;
        go(ii - posi, 1);
        if (posi == 1) {
            go(0, -1); ++jj;
            while (jj < j) {
                go(1, 1);
                go(-1, 1);
                go(0, -1); ++jj;
            }
        } else {
            go(0, -1); ++jj;
            while (jj < j) {
                go(-1, 1);
                go(1, 1);
                go(0, -1); ++jj;
            }
        }
    }
    while (posi > 1) go(-1, 0);
    while (posj > 1) go(0, -1);
    if (s[1][2] != t[1][2]) {
        go(0, 1);
        if (s[2][1] == t[1][2]) go(1, -1), go(-1, 0);
        else go(1, 0), go(-1, -1);
    }
    if (s[2][1] != t[2][1]) {
        go(1, 0);
        go(0, 1);
        go(-1, -1);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) {
        scanf("%d", s[i] + j);
        ++cnt[s[i][j]];
    }
    for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) {
        scanf("%d", t[i] + j);
        --cnt[t[i][j]];
    }
    for (int i = 1; i <= 900; ++i) if (cnt[i] != 0) {
        printf("-1\n");
        return 0;
    }
    if (n == 1) {
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j < i; ++j) {
                for (int k = 1; k <= m; ++k) tmp[k] = s[1][k];
                for (int k = i - 1; k >= j; --k)
                    swap(tmp[k], tmp[k + 1]);
                bool flag = true;
                for (int k = 1; k <= m; ++k) if (tmp[k] != t[1][k]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << i - j << '\n';
                    cout << 1 << ' ' << i << '\n';
                    for (int k = i - 1; k >= j; --k)
                        cout << 1 << ' ' << k << '\n';
                    return 0;
                }
            }
            for (int j = i + 1; j <= m; ++j) {
                for (int k = 1; k <= m; ++k) tmp[k] = s[1][k];
                for (int k = i + 1; k <= j; ++k)
                    swap(tmp[k], tmp[k - 1]);
                bool flag = true;
                for (int k = 1; k <= m; ++k) if (tmp[k] != t[1][k]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << j - i << '\n';
                    cout << 1 << ' ' << i << '\n';
                    for (int k = i + 1; k <= j; ++k)
                        cout << 1 << ' ' << k << '\n';
                    return 0;
                }
            }
        }
        cout << "-1\n";
        return 0;
    }
    if (m == 1) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j < i; ++j) {
                for (int k = 1; k <= n; ++k) tmp[k] = s[k][1];
                for (int k = i - 1; k >= j; --k)
                    swap(tmp[k], tmp[k + 1]);
                bool flag = true;
                for (int k = 1; k <= n; ++k) if (tmp[k] != t[k][1]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << i - j << '\n';
                    cout << i << ' ' << 1 << '\n';
                    for (int k = i - 1; k >= j; --k)
                        cout << k << ' ' << 1 << '\n';
                    return 0;
                }
            }
            for (int j = i + 1; j <= n; ++j) {
                for (int k = 1; k <= n; ++k) tmp[k] = s[k][1];
                for (int k = i + 1; k <= j; ++k)
                    swap(tmp[k], tmp[k - 1]);
                bool flag = true;
                for (int k = 1; k <= n; ++k) if (tmp[k] != t[k][1]) {
                    flag = false;
                    break;
                }
                if (flag) {
                    cout << j - i << '\n';
                    cout << i << ' ' << 1 << '\n';
                    for (int k = i + 1; k <= j; ++k)
                        cout << k << ' ' << 1 << '\n';
                    return 0;
                }
            }
        }
        cout << "-1\n";
        return 0;
    }
    bool flag = true;
    for (int i = 1; i <= n; ++i) if (flag) for (int j = 1; j <= m; ++j) if (s[i][j] == t[1][1]) {
        solve(i, j);
        flag = false;
        break;
    }
    printf("%d\n", (int)ans.size() - 1);
    REP(i, ans.size()) {
        printf("%d %d\n", ans[i].first, ans[i].second);
    }
    return 0;
}


#include <vector>
#include <stdio.h>
#include <assert.h>
#include <iostream>
using namespace std;
#define N 40
#define K 910
int getint(){
    int x=0; char c=getchar();
    while( c<'0'||c>'9' ) c=getchar();
    while(c>='0'&&c<='9') x*=10,x+=(c-'0'),c=getchar();
    return x;
}
vector< pair<int,int> > ans;
int n , m , tag;
int a[ N ][ N ] , b[ N ][ N ] , cnt[ K ];
void init(){
    n = getint(); m = getint();
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ ){
            a[ i ][ j ] = getint();
            cnt[ a[ i ][ j ] ] ++;
            if( cnt[ a[ i ][ j ] ] == 1 ) tag ++;
        }
    for( int i = 1 ; i <= n ; i ++ )
        for( int j = 1 ; j <= m ; j ++ ){
            b[ i ][ j ] = getint();
            cnt[ b[ i ][ j ] ] --;
            if( cnt[ b[ i ][ j ] ] == 0 ) tag --;
            if( cnt[ b[ i ][ j ] ] < 0 ) tag = 10000;
        }
}
void solve2(){
    if( n == 1 ){
        for( int i = 1 ; i <= m ; i++ )
            if( a[ 1 ][ i ] != b[ 1 ][ i ] ){
                for( int j = i + 1 ; j <= m ; j ++ ){
                    if( a[ 1 ][ j ] != b[ 1 ][ i ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k < j ; k ++ )
                        if( a[ 1 ][ k ] != b[ 1 ][ k + 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j + 1 ; k <= m ; k ++ )
                        if( a[ 1 ][ k ] != b[ 1 ][ k ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , j - i );
                        for( int k = j ; k >= i ; k -- )
                            printf( "1 %d\n" , k );
                        return;
                    }
                }
                break;
            }
        for( int i = m ; i >= 1 ; i -- )
            if( a[ 1 ][ i ] != b[ 1 ][ i ] ){
                for( int j = i - 1 ; j >= 1 ; j -- ){
                    if( a[ 1 ][ j ] != b[ 1 ][ i ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k > j ; k -- )
                        if( a[ 1 ][ k ] != b[ 1 ][ k - 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j - 1 ; k >= 1 ; k -- )
                        if( a[ 1 ][ k ] != b[ 1 ][ k ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , i - j );
                        for( int k = j ; k <= i ; k ++ )
                            printf( "1 %d\n" , k );
                        return;
                    }
                }
                break;
            }
        puts( "-1" );
        return;
    }else{
        for( int i = 1 ; i <= n ; i++ )
            if( a[ i ][ 1 ] != b[ i ][ 1 ] ){
                for( int j = i + 1 ; j <= n ; j ++ ){
                    if( a[ j ][ 1 ] != b[ i ][ 1 ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k < j ; k ++ )
                        if( a[ k ][ 1 ] != b[ k + 1 ][ 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j + 1 ; k <= n ; k ++ )
                        if( a[ k ][ 1 ] != b[ k ][ 1 ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , j - i );
                        for( int k = j ; k >= i ; k -- )
                            printf( "%d 1\n" , k );
                        return;
                    }
                }
            }
        for( int i = n ; i >= 1 ; i -- )
            if( a[ i ][ 1 ] != b[ i ][ 1 ] ){
                for( int j = i - 1 ; j >= 1 ; j -- ){
                    if( a[ j ][ 1 ] != b[ i ][ 1 ] )
                        continue;
                    bool tflag = true;
                    for( int k = i ; k > j ; k -- )
                        if( a[ k ][ 1 ] != b[ k - 1 ][ 1 ] ){
                            tflag = false; break;
                        }
                    for( int k = j - 1 ; k >= 1 ; k -- )
                        if( a[ k ][ 1 ] != b[ k ][ 1 ] ){
                            tflag = false; break;
                        }
                    if( tflag ){
                        printf( "%d\n" , i - j );
                        for( int k = j ; k <= i ; k ++ )
                            printf( "%d 1\n" , k );
                        return;
                    }
                }
                break;
            }
        puts( "-1" );
        return;
    }
}
int sn , sm;
void move( int ttn , int ttm ){
    while( sn != ttn && sm != ttm ){
        if( sn > ttn && sm > ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm - 1 ];
            a[ sn - 1 ][ sm - 1 ] = tswap;
            sn --; sm --;
        }else if( sn > ttn && sm < ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm + 1 ];
            a[ sn - 1 ][ sm + 1 ] = tswap;
            sn --; sm ++;
        }else if( sn < ttn && sm > ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm - 1 ];
            a[ sn + 1 ][ sm - 1 ] = tswap;
            sn ++; sm --;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm + 1 ];
            a[ sn + 1 ][ sm + 1 ] = tswap;
            sn ++; sm ++;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
    while( sn != ttn ){
        if( sn < ttn ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn + 1 ][ sm ];
            a[ sn + 1 ][ sm ] = tswap;
            sn ++;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn - 1 ][ sm ];
            a[ sn - 1 ][ sm ] = tswap;
            sn --;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
    while( sm != ttm ){
        if( sm < ttm ){
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn ][ sm + 1 ];
            a[ sn ][ sm + 1 ] = tswap;
            sm ++;
        }else{
            int tswap = a[ sn ][ sm ];
            a[ sn ][ sm ] = a[ sn ][ sm - 1 ];
            a[ sn ][ sm - 1 ] = tswap;
            sm --;
        }
//        printf( "%d %d\n" , sn , sm );
        ans.push_back( make_pair( sn , sm ) );
    }
}
void turn( int rn ){
    for( int i = m ; i >= 1 ; i -- ){
        move( 1 , 1 );
        if( a[ rn ][ i ] == b[ rn ][ i ] )
            continue;
        int xn = 0 , xm;
        for( int j = rn ; j >= 1 ; j -- ){
            for( int k = (j == rn ? i-1 :m) ; k >= 1 ; k -- )if( a[ j ][ k ] == b[ rn ][ i ] ){
                xn = j; xm = k; break;
            }
            if( xn ) break;
        }
        if( xm > i && xn < rn ){
            while( xm > i && xn < rn && xm - i > rn - xn ){
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }else{
                    move( xn - 1 , xm );
                    move( xn , xm - 1 );
                    move( xn , xm );
                    xm --;
                }
            }
        }
        while( xn != rn && xm != i ){
            if( xm < i ){
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }else{
                    move( xn - 1 , xm + 1 );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }
            }else{
                if( xn == 1 ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }else{
                    move( xn - 1 , xm - 1 );
                    move( xn + 1 , xm - 1 );
                    move( xn , xm );
                    xn ++; xm --;
                }
            }
        }
        while( xn != rn ){
            if( xn == 1 ){
                move( xn , xm - 1 );
                move( xn + 1 , xm );
                move( xn , xm );
                xn ++;
            }else{
                move( xn - 1 , xm );
                if( xm == 1 ) move( xn , xm + 1 );
                else move( xn , xm - 1 );
                move( xn + 1 , xm );
                move( xn , xm );
                xn ++;
            }
        }
        while( xm != i ){
assert( xn - 1 >= 1 && xm + 1 <= m );
            move( xn - 1 , xm );
            move( xn , xm + 1 );
            move( xn , xm );
            xm ++;
        }
    }
}
void turn2(){
    for( int j = m ; j >= 1 ; j -- )
        for( int i = 2 ; i >= 1 ; i -- ){
            move( 1 , 1 );
            if( a[ i ][ j ] == b[ i ][ j ] )
                continue;
            int xn = 0 , xm;
            for( int k = j ; k >= 1 ; k -- ){
                for( int l = (k==j? i - 1 : 2) ; l >= 1 ; l -- ){
                    if( a[ l ][ k ] == b[ i ][ j ] ){
                        xn = l; xm = k; break;
                    }
                }
                if( xn ) break;
            }
            while( xn != i && xm != j ){
                if( xn < i ){
                    move( xn + 1 , xm - 1 );
                    move( xn + 1 , xm + 1 );
                    move( xn , xm );
                    xn ++; xm ++;
                }else{
                    move( xn - 1 , xm + 1 );
                    move( xn , xm );
                    xn --; xm ++;
                }
            }
            while( xn != i ){
                if( xn < i ){
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn , xm );
                    xn ++;
                }else{
                    move( xn - 1 , xm );
                    move( xn , xm );
                    xn --;
                }
            }
            while( xm != j ){
                if( xn != 1 ){
                    move( xn - 1 , xm );
                    move( xn , xm + 1 );
                    move( xn , xm );
                    xm ++;
                }else{
                    move( xn , xm - 1 );
                    move( xn + 1 , xm );
                    move( xn , xm + 1 );
                    move( xn , xm );
                    xm ++;
                }
            }
        }
}
void solve3(){
    for( int i = 1 ; i <= n ; i ++ ){
        for( int j = 1 ; j <= m ; j ++ )
            if( a[ i ][ j ] == b[ 1 ][ 1 ] ){
                sn = i; sm = j;
                break;
            }
        if( sn ) break;
    }
    int an = sn , am = sm;
    move( 1 , 1 );
//    printf( "%d %d\n" , sn , sm );
    for( int i = n ; i > 2 ; i -- )
        turn( i );
    turn2();
    printf( "%d\n" , (int)ans.size() );
    printf( "%d %d\n" , an , am );
    for( int i = 0 ; i < (int)ans.size() ; i ++ )
        printf( "%d %d\n" , ans[ i ].first , ans[ i ].second );
}
void solve(){
    if( tag != 0 ){
        puts( "-1" );
        return;
    }
    if( n == 1 || m == 1 ) solve2();
    else solve3();
}
int main(){
    init();
    solve();
}

// ntuj - eg97gdnpa2egsf57qag2l


#include <bits/stdc++.h>

const int MAXN = 33;
const int MAXV = 909;

int n, m;
int arr[2][MAXN][MAXN];

bool solved() {
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            if (arr[0][i][j] != arr[1][i][j])
                return false;
    return true;
}

int x, y;
std::vector<std::pair<int, int>> as;

void STEP(int dx, int dy) {
    int nx = x + dx, ny = y + dy;
    std::swap(arr[0][x][y], arr[0][nx][ny]);
    as.push_back({nx, ny});
    x = nx, y = ny;
}

bool solve_line_left() {
    int bak[MAXN];
    for (int i = 1; i <= m; ++i) bak[i] = arr[0][1][i];

    for (int i = 1; i < m; ++i) {
        as.clear();
        x = 1, y = i;
        as.push_back({x, y});

        for (int j = i+1; j <= m; ++j) {
            STEP(0, 1);
            if (solved()) return true;
        }

        for (int j = 1; j <= m; ++j) arr[0][1][j] = bak[j];
    }

    return false;
}

bool solve_line() {
    if (solve_line_left()) return true;

    for (int k = 0; k < 2; ++k)
        for (int i = 1, j = m; i < j; ++i, --j)
            std::swap(arr[k][1][i], arr[k][1][j]);

    if (not solve_line_left()) return false;

    for (auto &p : as) p.second = m + 1 - p.second;

    return true;
}

void jizz() {
    x = -1, y = -1;
    for (int i = 1; x == -1 and i <= n; ++i)
        for (int j = 1; y == -1 and j <= m; ++j)
            if (arr[0][i][j] == arr[1][1][1])
                x = i, y = j;
    as.push_back({x, y});

    while (n > 2 or m > 2) {
        while (x < n) STEP(1, 0);
        while (y < m) STEP(0, 1);

        if (n > m) {
            int tx = n;
            for (int ty = m; ty >= 1; --ty) {
                int fx = -1, fy = -1;
                for (int i = 1; fx == -1 and i <= n; ++i)
                    for (int j = 1; fx == -1 and j <= m; ++j)
                        if (arr[0][i][j] == arr[1][tx][ty])
                            fx = i, fy = j;

                int x_bfr = fx == 1 ? 1 : -1;

                if (fy == ty) {
                    while (fx+1 < x) STEP(-1, 0);
                    if (x_bfr == -1) {
                        STEP(-1, 0);
                        fx += 1;
                    }
                } else {
                    int fix_dir = fy < ty ? 1 : -1;

                    while (fx < x) STEP(-1, 0);
                    while (fy != y) STEP(0, -fix_dir);
                    fy += fix_dir;

                    while (fy != ty) {
                        STEP(x_bfr, fix_dir);
                        STEP(-x_bfr, fix_dir);
                        STEP(0, -fix_dir);
                        fy += fix_dir;
                    }

                    STEP(x_bfr, fix_dir);
                }

                int y_bfr = fy == 1 ? 1 : -1;
                while (fx != tx) {
                    if (x < fx) {
                        STEP(1, y_bfr);
                        STEP(1, -y_bfr);
                    }
                    STEP(-1, 0);
                    fx += 1;
                }

                if (ty != 1) STEP(1, -1);
            }

            n -= 1;
        } else {
            int ty = m;
            for (int tx = n; tx >= 1; --tx) {
                int fx = -1, fy = -1;
                for (int j = 1; fx == -1 and j <= m; ++j)
                    for (int i = 1; fx == -1 and i <= n; ++i)
                        if (arr[0][i][j] == arr[1][tx][ty])
                            fx = i, fy = j;

                int y_bfr = fy == 1 ? 1 : -1;

                if (fx == tx) {
                    while (fy+1 < y) STEP(0, -1);
                    if (y_bfr == -1) {
                        STEP(0, -1);
                        fy += 1;
                    }
                } else {
                    int fix_dir = fx < tx ? 1 : -1;

                    while (fy < y) STEP(0, -1);
                    while (fx != x) STEP(-fix_dir, 0);
                    fx += fix_dir;

                    while (fx != tx) {
                        STEP(fix_dir, y_bfr);
                        STEP(fix_dir, -y_bfr);
                        STEP(-fix_dir, 0);
                        fx += fix_dir;
                    }

                    STEP(fix_dir, y_bfr);
                }

                int x_bfr = fx == 1 ? 1 : -1;
                while (fy != ty) {
                    if (y < fy) {
                        STEP(x_bfr, 1);
                        STEP(-x_bfr, 1);
                    }
                    STEP(0, -1);
                    fy += 1;
                }

                if (tx != 1) STEP(-1, 1);
            }

            m -= 1;
        }
    }

    while (not solved()) {
        int dx = x == 1 ? 1 : -1, dy = y == 1 ? 1 : -1;
        int tmp = rand() % 3;
        STEP(tmp == 1 ? 0 : dx, tmp == 2 ? 0 : dy);
    }
}

int main() {
    scanf("%d%d", &n, &m);

    std::vector<int> cnt(MAXV);

    for (int i = 0; i < 2; ++i) {
        for (int j = 1; j <= n; ++j) {
            for (int k = 1; k <= m; ++k) {
                int t; scanf("%d", &t);
                arr[i][j][k] = t, cnt[t] += i ? 1 : -1;
            }
        }
    }

    bool ok = true;
    for (int c : cnt) ok &= c == 0;

    if (not ok) {
        ;
    } else if (n == 1 or m == 1) {
        bool tp = m == 1;
        if (tp) {
            for (int i = 0; i < 2; ++i)
                for (int j = 2; j <= n; ++j)
                    arr[i][1][j] = arr[i][j][1];
            std::swap(n, m);
        }

        ok = solve_line();

        if (tp)
            for (auto &p : as)
                std::swap(p.first, p.second);
    } else {
        jizz();
    }

    if (ok) {
        printf("%u\n", as.size() - 1);
        for (auto p : as) printf("%d %d\n", p.first, p.second);
    } else {
        puts("-1");
    }

    return 0;
}
// ntuj - hbov48loso08rh3pi1gqb


#include<bits/stdc++.h>
using namespace std;
#define _SZ(n) memset((n),0,sizeof(n))
#define _SMO(n) memset((n),-1,sizeof(n))
#define _MC(n,m) memcpy((n),(m),sizeof(n))
#define _F first
#define _S second
#define _MP make_pair
#define _PB push_back
#define FOR(x,y) for(__typeof(y.begin())x=y.begin();x!=y.end();x++)
#define IOS ios_base::sync_with_stdio(0)
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
  freopen(name".in", "r", stdin); \
  freopen(name".out", "w", stdout);
#else
#define FILEIO(name)
#endif
// Let's Fight!

const int MX = 35;

struct Point{
  int x,y;
  Point () {}
  Point (int _x, int _y) : x(_x), y(_y) {}
  bool operator == (const Point &b) const{
    return x == b.x && y == b.y;
  }
  bool operator != (const Point &b) const{
    return !(*this == b);
  }
};

int N,M,ip[MX][MX],op[MX][MX];
Point p(-1,-1), q; // p move q to ed
vector<Point> ans;
vector<Point> seq;
int bad[MX][MX];
Point prv[MX][MX];
Point que[MX*MX];
int vst[MX][MX];
int fr,bk;
int dir[8][2] = {{-1,0},{1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
vector<Point> path;

void BFS(Point ed){
//  printf("BFS %d %d -> %d %d\n", p.x, p.y, ed.x, ed.y);
  fr = bk = 0;
  _SZ(vst);
  que[bk++] = p;
  vst[p.x][p.y] = 1;
  while (fr < bk){
    Point u = que[fr++];
    for (int i=0; i<8; i++){
      int nx = u.x + dir[i][0];
      int ny = u.y + dir[i][1];
      if (nx < 1 || ny < 1 || nx > N || ny > M) continue;
      if (bad[nx][ny]) continue;
      if (q.x == nx && q.y == ny) continue;
      if (vst[nx][ny]) continue;
      que[bk++] = Point(nx,ny);
      prv[nx][ny] = u;
      vst[nx][ny] = 1;
    }
    if (vst[ed.x][ed.y]) break;
  }
  assert(vst[ed.x][ed.y] == 1);
  path.clear();
  Point cur = ed;
  while (cur != p){
    path._PB(cur);
    cur = prv[cur.x][cur.y];
  }
  reverse(path.begin(),path.end());
}
void move(Point a){
  if (ans.size()){
    assert(a != ans.back());
  }
  ans._PB(a);
  swap(ip[a.x][a.y],ip[p.x][p.y]);
  p = a;
}
void solve(Point ed){
  q = Point(-1,-1);
  for (int i=1; i<=N && q.x==-1; i++){
    for (int j=1; j<=M && q.x==-1; j++){
      if (bad[i][j]) continue;
      if (p.x == i && p.y == j) continue;
      if (ip[i][j] == op[ed.x][ed.y])
        q = Point(i,j);
    }
  }
  int dx=1;
  int dy=1;
  if (ed.x < q.x) dx = -1;
  if (ed.y < q.y) dy = -1;
  while (q != ed){
    if (q.x != ed.x && q.y != ed.y && !bad[q.x+dx][q.y+dy]){
      BFS(Point(q.x+dx,q.y+dy));
    } else if (q.x != ed.x && !bad[q.x+dx][q.y]){
      BFS(Point(q.x+dx,q.y));
    } else if (q.y != ed.y && !bad[q.x][q.y+dy]){
      BFS(Point(q.x,q.y+dy));
    } else {
      assert(false);
    }
      for (auto i : path)
        move(i);
      Point tmp = p;
      move(q);
      q = tmp;
  }
}
void solve_seq(){
  for (auto v : seq){
    solve(v);
    bad[v.x][v.y] = 1;
  }
}
void solve22(){
  if (p != Point(1,1)){
    q = Point(-1,-1);
    BFS(Point(1,1));
    for (auto i : path){
      move(i);
    }
  }
  if (ip[2][2] != op[2][2]){
    if (ip[1][2] == op[2][2]){
      move(Point(2,2));
      move(Point(1,2));
    } else if (ip[2][1] == op[2][2]){
      move(Point(2,2));
      move(Point(2,1));
    }
  }
  if (p != Point(1,1)){
    move(Point(1,1));
  }
  if (ip[1][2] != op[1][2]){
    move(Point(2,1));
    move(Point(1,2));
  }
  if (p != Point(1,1)){
    move(Point(1,1));
  }
}
bool check(Point st, Point ed){
  int dx = 0;
  int dy = 0;
  if (ed.x < st.x) dx = -1;
  if (ed.x > st.x) dx = 1;
  if (ed.y < st.y) dy = -1;
  if (ed.y > st.y) dy = 1;
  int tp[MX][MX];
  for (int i=0; i<MX; i++)
    for (int j=0; j<MX; j++)
      tp[i][j] = ip[i][j];
  ans.clear();
  while (st != ed){
    ans._PB(st);
    swap(tp[st.x][st.y],tp[st.x+dx][st.y+dy]);
    st.x += dx;
    st.y += dy;
  }
  ans._PB(ed);
  int fail=0;
  for (int i=1; i<=N && !fail; i++)
    for (int j=1; j<=M && !fail; j++)
      if (tp[i][j] != op[i][j])
        fail = 1;
  return !fail;
}
int main()
{
  int c1[MX*MX] = {0};
  int c2[MX*MX] = {0};
  scanf("%d%d", &N, &M);
  for (int i=1; i<=N; i++){
    for (int j=1; j<=M; j++){
      scanf("%d", &ip[i][j]);
      c1[ip[i][j]]++;
    }
  }
  for (int i=1; i<=N; i++){
    for (int j=1; j<=M; j++){
      scanf("%d", &op[i][j]);
      c2[op[i][j]]++;
    }
  }
  for (int i=1; i<MX*MX; i++){
    if (c1[i] != c2[i]){
      puts("-1");
      return 0;
    }
  }
  if (N == 1 || M == 1){
    vector<Point> pt;
    for (int i=1; i<=N; i++)
      for (int j=1; j<=M; j++)
        pt._PB(Point(i,j));
    int n = pt.size();
    int ok = 0;
    for (int i=0; i<n && !ok; i++){
      for (int j=0; j<n && !ok; j++){
        if (i == j) continue;
        if (check(pt[i],pt[j])){
          ok = 1;
        }
      }
    }
    if (ok){
      printf("%d\n", (int)ans.size()-1);
      for (auto i : ans)
        printf("%d %d\n", i.x, i.y);
    } else {
      puts("-1");
    }
  } else {
    p = Point(-1,-1);
    for (int i=1; i<=N && p.x == -1; i++){
      for (int j=1; j<=M && p.x == -1; j++){
        if (ip[i][j] == op[1][1]){
          p = Point(i,j);
        }
      }
    }
    int x = p.x;
    int y = p.y;
    for (int j=M; j>2; j--){
      for (int i=N; i>=1; i--){
        seq._PB(Point(i,j));
      }
    }
    for (int i=N; i>2; i--){
      seq._PB(Point(i,2));
      seq._PB(Point(i,1));
    }
    _SZ(bad);
    solve_seq();

    for (int i=1; i<=N; i++){
      for (int j=1; j<=M; j++){
        if (i>2 && j>2 && ip[i][j] != op[i][j]){
          assert(false);
        }
      }
    }

    solve22();
    for (int i=1; i<=N; i++){
      for (int j=1; j<=M; j++){
        if (ip[i][j] != op[i][j]){
          assert(false);
        }
      }
    }
    assert(ans.size() <= 1000000);
    printf("%d\n", (int)ans.size());
    printf("%d %d\n", x, y);
    for (auto i : ans)
      printf("%d %d\n", i.x, i.y);
  }

  return 0;
}

// ntuj - iqp2g2lglhnk6dnpphzmi


//by david942j
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <map>
#include <queue>
#include <iostream>
#include <set>
#include <cassert>
#include <stack>
#define PAUSE fgetc(stdin);
#include <string>
#include <cmath>
#include <algorithm>
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define __count(x) __builtin_popcount(x)
#define RI(x) scanf("%d",&x)
#define RI2(a,b) scanf("%d%d",&a,&b)
#define RI3(a,b,c) scanf("%d%d%d",&a,&b,&c)
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
const int N=40, lgN=20;
const int INF=2000000000;
int n,m,*A[N],*B[N];
bool fail;
bool rev;
vector<PII> ans;

int *bA[N];
void print(int **A,int n,int m) {
    FOR(i,n)FOR(j,m)printf("%d%c",A[i][j],j==m-1?'\n':' ');
}
int **reflex(int n,int m,int **A) {
    int **B=new int*[m];
    FOR(i,m)B[i]=new int[n];
    FOR(i,n)FOR(j,m)B[j][i]=A[i][j];
    return B;
}
bool same(int **A,int **B,int n,int m) {
    FOR(i,n)FOR(j,m)if(A[i][j]!=B[i][j])return false;
    return true;
}
void find_c(int n,int m,int p,int **A,int c,int &x,int &y) {
    FOR(j,m)FOR(i,n)
    if(i+j==0)continue;
    else if(j==m-1 && i>=p)return;
    else if(A[i][j]==c) {
        x=i;y=j;
        return;
    }
}
enum {
    UP=0,
    DOWN=1,
    LEFT=2,
    RIGHT=3,
    RU=4,
    RD=5,
    LD=6,
    LU=7
};
int dx[]={-1,1,0,0,-1,1,1,-1},dy[]={0,0,-1,1,1,1,-1,-1};
void udlr(int **A,int &x,int &y,int d) {
    swap(A[x][y],A[x+dx[d]][y+dy[d]]);
    x+=dx[d];y+=dy[d];
    if(rev)ans.pb(mpr(y,x));
    else ans.pb(mpr(x,y));
}
void d_move(int **A,int &x,int &y,int a,int b) {
    while(x!=a || y!=b) {
        if(x>a)udlr(A,x,y,0);
        else if(x<a)udlr(A,x,y,1);
        else if(y>b)udlr(A,x,y,2);
        else if(y<b)udlr(A,x,y,3);
    }
}

void make_up(int **A,int &x,int &y) {
    udlr(A,x,y,DOWN);
    if(x==1)return;
    if(y>0) {
        udlr(A,x,y,LU);
        udlr(A,x,y,RU);
        make_up(A,x,y);
    }
    else {
        udlr(A,x,y,RU);
        udlr(A,x,y,LU);
        make_up(A,x,y);
    }
}
void make_right(int **A,int &x,int &y,int m) {
    udlr(A,x,y,RU);
    udlr(A,x,y,LEFT);
    if(y==m-2)return;
    udlr(A,x,y,RD);
    make_right(A,x,y,m);
}
void make_down(int **A,int &x,int &y,int n) {
    udlr(A,x,y,RD);
    udlr(A,x,y,UP);
    if(x==n-2)return;
    udlr(A,x,y,LD);
    make_down(A,x,y,n);
}
void just_go(int x,int a,int **A) {
    if(x==a)return;
    if(x<a) {
        for(int i=x+1;i<=a;i++)
            swap(A[0][i],A[0][i-1]);
    }
    else {
        for(int i=x-1;i>=a;i--)
            swap(A[0][i],A[0][i+1]);
    }
}
void solve1(int n,int m,int **A,int **B) {
    if(n>m) {
        int **C,**D;
        C=reflex(n,m,A);
        D=reflex(n,m,B);
        rev^=1;
        return solve1(m,n,C,D);
    }
    FOR(i,m)FOR(j,m) {
        just_go(i,j,A);
        if(same(A,B,1,m)) {
            int x=0,y=i;
            if(rev)ans.pb(mpr(y,x));
            else ans.pb(mpr(x,y));
            d_move(A,x,y,0,j);
            return;
        }
        just_go(j,i,A);
    }
    fail=true;
}
void solve22(int **A,int **B) {
    int x=0,y=0;
    int step=0;
    while(true) {
        if(same(A,B,2,2))return;
        if(step>1000){fail=true;return;}
        while(true) {
            int r=rand()%8;
            int a=x+dx[r],b=y+dy[r];
            if(a<0||a>=2||b<0||b>=2)continue;
            udlr(A,x,y,r);
            step++;
            break;
        }
    }
}
void solve(int n,int m,int **A,int **B) {
    if(n>m) {
        int **C,**D;
        C=reflex(n,m,A);
        D=reflex(n,m,B);
        rev^=1;
        return solve(m,n,C,D);
    }
    if(n==2 && m==2)
        return solve22(A,B);
    for(int i=n-1;i>=0;i--) {
        int x=-1,y=-1;
        if(A[i][m-1]==B[i][m-1])continue;
        find_c(n,m,i,A,B[i][m-1],x,y);
        if(x==-1){fail=true;return;}
        int nowx=0,nowy=0;
        if(x==0) {
            d_move(A,nowx,nowy,x,y-1);
            udlr(A,nowx,nowy,RD);
        }
        else {
            d_move(A,nowx,nowy,x-1,y);
            make_up(A,nowx,nowy); //make nowx+1,nowy to top
        }
        if(nowy==m-1)
            udlr(A,nowx,nowy,LU);
        else make_right(A,nowx,nowy,m); //make nowx-1,nowy to rightest
        if(nowx==i)d_move(A,nowx,nowy,0,0);//back
        else {
            make_down(A,nowx,nowy,i+1);//make nowx,nowy+1 to i,nowy+1
            d_move(A,nowx,nowy,0,0);//back
        }
    }
    solve(n,m-1,A,B);
}
int main() {
    FOR(i,N)A[i]=new int [N],bA[i]=new int [N];
    FOR(i,N)B[i]=new int [N];
    RI2(n,m);
    FOR(i,n)FOR(j,m)RI(A[i][j]),bA[i][j]=A[i][j];
    FOR(i,n)FOR(j,m)RI(B[i][j]);
    if(min(n,m)==1) solve1(n,m,A,B);
    else {
        if(A[0][0]!=B[0][0]) {
            int x=-1,y;
            find_c(n,m,N,A,B[0][0],x,y);
            if(x==-1){puts("-1");return 0;}
            ans.pb(mpr(x,y));
            d_move(A,x,y,0,0);
        }
        else ans.pb(mpr(0,0));
        solve(n,m,A,B);
    }
    if(fail)puts("-1");
    else {
        printf("%d\n",ans.size());
        FOR(i,ans.size())
            printf("%d %d\n",ans[i].X+1,ans[i].Y+1);
    }
    /*FOR1(i,(int)ans.size()-1) {
        swap(bA[ans[i-1].X][ans[i-1].Y],bA[ans[i].X][ans[i].Y]);
    }*/
    //print(bA,n,m);
}
/*

  2 6
  1 2 3 4 5 6
  7 8 9 1 2 3

  1 6 5 4 3 2
  3 7 8 1 2 9

  3 3
  1 3 9
  2 4 1
  6 7 2

  4 7 6
  2 9 3
  1 1 2

  2 2
  1 3
  2 3
  1 3
  3 2

  2 2
  1 3
  2 3
  1 2
  2 3

  1 4
  1 2 3 4
  4 3 2 1

  4 1
  1
  2
  3
  4
  3
  1
  2
  4

 */
// ntuj - 8xsjpx49r96abwv8zz2xt


#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define _SZ(n) memset((n),0,sizeof(n))
#define _SMO(n) memset((n),-1,sizeof(n))
#define _MC(n,m) memcpy((n),(m),sizeof(n))
#define _F first
#define _S second
#define _MP make_pair
#define _PB push_back
#define FOR(x,y) for(__typeof(y.begin())x=y.begin();x!=y.end();x++)
#define IOS ios_base::sync_with_stdio(0)

#ifdef ONLINE_JUDGE
#define FILEIO(name) \
	freopen(name".in", "r", stdin); \
    freopen(name".out", "w", stdout);
#else
#define FILEIO(name)
#endif
// Let's Fight!

typedef pair<int, int> pii;

const int MAXN = 32;
const int MAXP = 999;

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

int N, M;
int arr[MAXN][MAXN], brr[MAXN][MAXN];
int orr[MAXN][MAXN];
int acnt[MAXP], bcnt[MAXP];
int used[MAXN][MAXN];
pii prv[MAXN][MAXN];
vector<pii> vans;
int nx, ny;

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

void success()
{
    cout<<vans.size()-1<<"\n";
    FOR(it, vans)
        cout<<it->_F<<" "<<it->_S<<"\n";
    exit(0);
}

bool valid(int x, int y)
{
    return x>=0 && x<N && y>=0 && y<N && !used[x][y];
}

void step(int x, int y)
{
    vans._PB(_MP(x+1, y+1));
    swap(arr[nx][ny], arr[x][y]);
    nx = x, ny = y;
}

vector<pii> get_path(int sx, int sy, int tx, int ty)
{
    _SMO(prv);
    queue<pii> Q;
    prv[tx][ty] = _MP(-2, -2);
    Q.push(_MP(tx, ty));
    while(!Q.empty())
    {
        int vx = Q.front()._F, vy = Q.front()._S;
        if(vx == sx && vy == sy)break;
        Q.pop();
        for(int i=0; i<8; i++)
        {
            int qx = vx + dx[i], qy = vy + dy[i];
            if(valid(qx, qy) && prv[qx][qy]._F == -1)
            {
                prv[qx][qy] = _MP(vx, vy);
                Q.push(_MP(qx, qy));
            }
        }
    }

    vector<pii> ret;
    int nowx = sx, nowy = sy;
    while(nowx != tx || nowy != ty)
    {
        pii tmp = prv[nowx][nowy];
        nowx = tmp._F;
        nowy = tmp._S;
        ret._PB(tmp);
    }
    return ret;
}

void go(int x, int y)
{
    vector<pii> vpath = get_path(nx, ny, x, y);
    FOR(it, vpath)
    {
        step(it->_F, it->_S);
    }
}

void print(int a[MAXN][MAXN])
{
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
            cout<<a[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}

void move_orb(int x, int y)
{
    go(x, y);
    // print(arr);
    int px = -1, py = -1;
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
        {
            if(used[i][j])continue;
            if(i==x && j==y)continue;
            if(arr[i][j] != brr[x][y])continue;

            px = i;
            py = j;
        }
    }

    // cout<<x<<","<<y<<" P "<<px<<","<<py<<endl;

    vector<pii> vpath = get_path(px, py, x, y);
    FOR(it, vpath)
    {
        used[px][py] = true;
        go(it->_F, it->_S);
        used[px][py] = false;
        step(px, py);
        px = it->_F;
        py = it->_S;
    }

    used[x][y] = true;
}

bool check()
{
    for(int i=0; i<N; i++)
        for(int j=0; j<M; j++)
            if(arr[i][j] != brr[i][j])
                return false;
    return true;
}

int main()
{
    IOS;
    cin>>N>>M;
    for(int i=0; i<N; i++)
        for(int j=0; j<M; j++)
            cin>>arr[i][j];
    for(int i=0; i<N; i++)
        for(int j=0; j<M; j++)
            cin>>brr[i][j];

    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
        {
            acnt[arr[i][j]]++;
            bcnt[brr[i][j]]++;
        }
    }

    for(int i=0; i<MAXP; i++)
        if(acnt[i] != bcnt[i])
            fail();

    if(N == 1 || M == 1)
    {
        for(int i=0; i<N; i++)
            for(int j=0; j<M; j++)
                orr[i][j] = arr[i][j];
        int X = max(N, M);
        for(int i=0; i<X; i++)
        {
            for(int j=0; j<X; j++)
            {
                if(i == j)continue;
                vans.clear();
                for(int ii=0; ii<N; ii++)
                    for(int jj=0; jj<M; jj++)
                        arr[ii][jj] = orr[ii][jj];

                nx = ny = 0;
                if(N == 1)vans._PB(_MP(1, i+1)), ny = i;
                else vans._PB(_MP(i+1, 1)), nx = i;

                for(int k=i; k!=j; )
                {
                    if(k<j)k++;
                    else k--;
                    // cout<<"STEP "<<min(k, N-1)<<","<<min(k, M-1)<<endl;
                    step(min(k, N-1), min(k, M-1));
                }

                // cout<<i<<" "<<j<<endl;
                // print(arr);

                if(check())
                    success();
            }
        }
        fail();
    }

    for(int i=0; i<N; i++)
        for(int j=0; j<M; j++)
            if(arr[i][j] == brr[0][0])
                nx = i, ny = j;
    vans._PB(_MP(nx+1, ny+1));

    // move_orb(N-1, M-1);
    for(int i=N-1; i>=2; i--)
        for(int j=M-1; j>=0; j--)
            move_orb(i, j);
    for(int j=N-1; j>=0; j--)
        for(int i=1; i>=0; i--)
            if(i!=0 || j!=0)
                move_orb(i, j);

    // print(arr);
    // print(brr);

    success();

	return 0;
}

// ntuj - 4e9us3mk9g80bybukiarg


#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<string>
#include<string.h>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<cctype>
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rrep(i,n) for(int i = 1; i <= n; ++i)
#define drep(i,n) for(int i = n-1; i >= 0; --i)
#define gep(i,g,j) for(int i = g.head[j]; i != -1; i = g.e[i].next)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define rng(a) a.begin(),a.end()
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define pb push_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcount
#define snuke srand((unsigned)clock()+(unsigned)time(NULL))
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
typedef vector<int> vi;

const int MX = 1000005, INF = 1000010000;
const ll LINF = 1000000000000000000ll;
const double eps = 1e-10;
const int dx[] = {-1,-1,-1,0,0,1,1,1}, dy[] = {-1,0,1,-1,1,-1,0,1}; //<^>v

int n, m;
int s[35][35];
int t[35][35];
int u[35][35];
int cnt[905];
int used[35][35], ui;
int px[35][35], py[35][35];
vector<P> p;

int x, y;
void bfs(int a, int b) {
	queue<P> q;
	q.push(P(a,b));
	used[a][b] = ++ui;
	px[a][b] = -1;
	while (q.size()) {
		int i = q.front().fi, j = q.front().se; q.pop();
		rep(v,8) {
			int ni = i+dx[v], nj = j+dy[v];
			if (ni<0||nj<0||ni>=n||nj>=m||s[ni][nj]==-1||used[ni][nj]==ui) continue;
			used[ni][nj] = ui;
			px[ni][nj] = i;
			py[ni][nj] = j;
			q.push(P(ni,nj));
		}
	}
	while (px[x][y] != -1) {
		int i = x, j = y;
		x = px[i][j]; y = py[i][j];
		swap(s[i][j],s[x][y]);
		p.pb(P(x,y));
	}
}
void f() {
	rep(i,n)rep(j,m) if (t[n-1][m-1] == s[i][j]) x = i, y = j;
	p.pb(P(x,y));
	rep(i,n-2) {
		rep(j,m) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j]) a = ai, b = bi;
			s[a][b] = -1;
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (b < j) {
				bfs(a,b+1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(a,x);
				p.pb(P(x,y));
			}
		}
	}
	rep(j,m-1) {
		for(int i = n-2; i < n; ++i) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j]) a = ai, b = bi;
			s[a][b] = -1;
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (a < i) {
				bfs(a+1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(b,y);
				p.pb(P(x,y));
			}
		}
	}
	if (x != n-1) p.pb(P(x+1,y));
	printf("%d\n",sz(p)-1);
	rep(i,sz(p)) {
		printf("%d %d\n",p[i].fi+1,p[i].se+1);
	}
}

int main(){
	scanf("%d%d",&n,&m);
	rep(i,n)rep(j,m) scanf("%d",&s[i][j]);
	rep(i,n)rep(j,m) scanf("%d",&t[i][j]);
	rep(i,n)rep(j,m) cnt[s[i][j]]++;
	rep(i,n)rep(j,m) cnt[t[i][j]]--;
	rep(i,905) if (cnt[i]) {
		puts("-1");
		return 0;
	}
	if (n == 1) {
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < m; ++k) {
				swap(u[0][k],u[0][k-1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si+1);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[0][k],u[0][k+1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k+1);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}
	if (m == 1) {
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < n; ++k) {
				swap(u[k][0],u[k-1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si+1);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[k][0],u[k+1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k+1);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}

	f();

	return 0;
}


#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<string>
#include<string.h>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<cctype>
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rrep(i,n) for(int i = 1; i <= n; ++i)
#define drep(i,n) for(int i = n-1; i >= 0; --i)
#define gep(i,g,j) for(int i = g.head[j]; i != -1; i = g.e[i].next)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define rng(a) a.begin(),a.end()
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define pb push_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcount
#define snuke srand((unsigned)clock()+(unsigned)time(NULL))
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
typedef vector<int> vi;

const int MX = 1000005, INF = 1000010000;
const ll LINF = 1000000000000000000ll;
const double eps = 1e-10;
const int dx[] = {-1,-1,-1,0,0,1,1,1}, dy[] = {-1,0,1,-1,1,-1,0,1}; //<^>v

int n, m;
int s[35][35];
int t[35][35];
int u[35][35];
int cnt[905];
int used[35][35], ui;
int px[35][35], py[35][35];
vector<P> p;

int x, y;
void bfs(int a, int b) {
	//printf("in %d %d\n",a,b);
	queue<P> q;
	q.push(P(a,b));
	used[a][b] = ++ui;
	px[a][b] = -1;
	while (q.size()) {
		int i = q.front().fi, j = q.front().se; q.pop();
		if (i == x && j == y) break;
		rep(v,8) {
			int ni = i+dx[v], nj = j+dy[v];
			if (ni<0||nj<0||ni>=n||nj>=m||s[ni][nj]==-1||used[ni][nj]==ui) continue;
			used[ni][nj] = ui;
			px[ni][nj] = i;
			py[ni][nj] = j;
			q.push(P(ni,nj));
		}
	}
	/*
	if (used[x][y] != ui) {
		printf("in %d %d\n",a,b);
		printf("out %d %d\n",x,y);
		rep(i,n){rep(j,m)printf("%2d",s[i][j]);puts("");}
		puts("no");
	}//*/
	while (px[x][y] != -1) {
		int i = x, j = y;
		x = px[i][j]; y = py[i][j];
		swap(s[i][j],s[x][y]);
		p.pb(P(x,y));
	}
	//printf("out %d %d\n",x,y);
}
void f() {
	rep(i,n)rep(j,m) if (t[n-1][m-1] == s[i][j]) x = i, y = j;
	p.pb(P(x,y));
	rep(i,n-2) {
		rep(j,m) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j] && (ai!=x||bi!=y)) a = ai, b = bi;
			s[a][b] = -1;
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (b < j) {
				bfs(a,b+1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(a,x);
				p.pb(P(x,y));
			}
		}
	}
	rep(j,m-1) {
		for(int i = n-2; i < n; ++i) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j]) a = ai, b = bi;
			s[a][b] = -1;
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (a < i) {
				bfs(a+1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(b,y);
				p.pb(P(x,y));
			}
		}
	}
	if (x != n-1) p.pb(P(x+1,y));
	printf("%d\n",sz(p)-1);
	rep(i,sz(p)) {
		printf("%d %d\n",p[i].fi+1,p[i].se+1);
	}
}

void check() {
	rep(i,sz(p)-1) {
		swap(u[p[i].fi][p[i].se],u[p[i+1].fi][p[i+1].se]);
	}
	rep(i,n){rep(j,m) printf("%d ",u[i][j]); puts("");}
}

int main(){
	scanf("%d%d",&n,&m);
	rep(i,n)rep(j,m) scanf("%d",&s[i][j]);
	rep(i,n)rep(j,m) scanf("%d",&t[i][j]);
	rep(i,n)rep(j,m) cnt[s[i][j]]++;
	rep(i,n)rep(j,m) cnt[t[i][j]]--;
	rep(i,905) if (cnt[i]) {
		puts("-1");
		return 0;
	}
	if (n == 1) {
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < m; ++k) {
				swap(u[0][k],u[0][k-1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[0][k],u[0][k+1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}
	if (m == 1) {
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < n; ++k) {
				swap(u[k][0],u[k-1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[k][0],u[k+1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}

	rep(i,n)rep(j,m) u[i][j] = s[i][j];
	f();
	//check();

	return 0;
}


#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<string>
#include<string.h>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<cctype>
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rrep(i,n) for(int i = 1; i <= n; ++i)
#define drep(i,n) for(int i = n-1; i >= 0; --i)
#define gep(i,g,j) for(int i = g.head[j]; i != -1; i = g.e[i].next)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define rng(a) a.begin(),a.end()
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define pb push_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcount
#define snuke srand((unsigned)clock()+(unsigned)time(NULL))
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
typedef vector<int> vi;

const int MX = 1000005, INF = 1000010000;
const ll LINF = 1000000000000000000ll;
const double eps = 1e-10;
const int dx[] = {-1,-1,-1,0,0,1,1,1}, dy[] = {-1,0,1,-1,1,-1,0,1}; //<^>v

int n, m;
int s[35][35];
int t[35][35];
int u[35][35];
int cnt[905];
int used[35][35], ui;
int px[35][35], py[35][35];
vector<P> p;

int x, y;
void bfs(int a, int b) {
	//printf("in %d %d\n",a,b);
	queue<P> q;
	q.push(P(a,b));
	used[a][b] = ++ui;
	px[a][b] = -1;
	while (q.size()) {
		int i = q.front().fi, j = q.front().se; q.pop();
		if (i == x && j == y) break;
		rep(v,8) {
			int ni = i+dx[v], nj = j+dy[v];
			if (ni<0||nj<0||ni>=n||nj>=m||s[ni][nj]==-1||used[ni][nj]==ui) continue;
			used[ni][nj] = ui;
			px[ni][nj] = i;
			py[ni][nj] = j;
			q.push(P(ni,nj));
		}
	}
	/*
	if (used[x][y] != ui) {
		printf("in %d %d\n",a,b);
		printf("out %d %d\n",x,y);
		rep(i,n){rep(j,m)printf("%2d",s[i][j]);puts("");}
		puts("no");
	}//*/
	while (px[x][y] != -1) {
		int i = x, j = y;
		x = px[i][j]; y = py[i][j];
		swap(s[i][j],s[x][y]);
		p.pb(P(x,y));
	}
	//printf("out %d %d\n",x,y);
}
void f() {
	rep(i,n)rep(j,m) if (t[n-1][m-1] == s[i][j]) x = i, y = j;
	p.pb(P(x,y));
	rep(i,n-2) {
		rep(j,m) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j] && (ai!=x||bi!=y)) a = ai, b = bi;
			s[a][b] = -1;
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (b < j) {
				bfs(a,b+1);
				swap(s[x][y],s[a][b]);
				swap(y,b);
				p.pb(P(x,y));
			}
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(a,x);
				p.pb(P(x,y));
			}
		}
	}
	rep(j,m-1) {
		for(int i = n-2; i < n; ++i) {
			int a, b;
			rep(ai,n)rep(bi,m) if (s[ai][bi] == t[i][j] && (ai!=x||bi!=y)) a = ai, b = bi;
			s[a][b] = -1;
			while (a > i) {
				bfs(a-1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (a < i) {
				bfs(a+1,b);
				swap(s[x][y],s[a][b]);
				swap(x,a);
				p.pb(P(x,y));
			}
			while (b > j) {
				bfs(a,b-1);
				swap(s[x][y],s[a][b]);
				swap(b,y);
				p.pb(P(x,y));
			}
		}
	}
	if (x != n-1) p.pb(P(x+1,y));
	printf("%d\n",sz(p)-1);
	rep(i,sz(p)) {
		printf("%d %d\n",p[i].fi+1,p[i].se+1);
	}
}

void check() {
	rep(i,sz(p)-1) {
		swap(u[p[i].fi][p[i].se],u[p[i+1].fi][p[i+1].se]);
	}
	rep(i,n){rep(j,m) printf("%d ",u[i][j]); puts("");}
}

int main(){
	scanf("%d%d",&n,&m);
	rep(i,n)rep(j,m) scanf("%d",&s[i][j]);
	rep(i,n)rep(j,m) scanf("%d",&t[i][j]);
	rep(i,n)rep(j,m) cnt[s[i][j]]++;
	rep(i,n)rep(j,m) cnt[t[i][j]]--;
	rep(i,905) if (cnt[i]) {
		puts("-1");
		return 0;
	}
	if (n == 1) {
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < m; ++k) {
				swap(u[0][k],u[0][k-1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		rep(si,m){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[0][k],u[0][k+1]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",1,i+1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}
	if (m == 1) {
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si+1; k < n; ++k) {
				swap(u[k][0],u[k-1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",k-si);
					for(int i = si; i <= k; ++i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		rep(si,n){
			rep(i,n)rep(j,m) u[i][j] = s[i][j];
			for (int k = si-1; k >= 0; --k) {
				swap(u[k][0],u[k+1][0]);
				bool ok = true;
				rep(i,n)rep(j,m) if(u[i][j] != t[i][j]) ok = false;
				if (ok) {
					printf("%d\n",si-k);
					for(int i = si; i >= k; --i) {
						printf("%d %d\n",i+1,1);
					}
					return 0;
				}
			}
		}
		puts("-1");
		return 0;
	}

	rep(i,n)rep(j,m) u[i][j] = s[i][j];
	f();
	//check();

	return 0;
}