#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int n,m,cnt,a[40][40],b[40][40];
struct point
{
    int x,y;
    point(int _x=-1,int _y=-1) {x=_x;y=_y;}
}p[1000005],target,cur;
bool check(int a[40][40])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) if(a[i][j]!=b[i][j]) return false;
    return true;
}
void output()
{
    printf("%d\n",cnt-1);
    for(int i=0;i<cnt;i++) printf("%d %d\n",p[i].x+1,p[i].y+1);
}
inline void GoDirection(int k)
{
    int dx=cur.x+d[k][0],dy=cur.y+d[k][1];
    swap(a[dx][dy],a[cur.x][cur.y]);
    cur=point(dx,dy);
    p[cnt++]=point(dx,dy);
}
point Find()
{
    int val=b[target.x][target.y];
    for(int i=target.x-1;i>=0;i--)
    {
        if(i==cur.x&&target.y==cur.y) continue;
        if(a[i][target.y]==val) return point(i,target.y);
    }
    for(int j=target.y-1;j>=0;j--)
        for(int i=n-1;i>=0;i--)
        {
            if(i==cur.x&&j==cur.y) continue;
            if(a[i][j]==val) return point(i,j);
        }
}
void GoToPoint(int x,int y)
{
    if(cur.x==x&&cur.y==y) return ;
    if(cur.y==y)
    {
        while(cur.x<x) GoDirection(6);
        while(cur.x>x) GoDirection(1);
    }
    else
    {
        while(cur.x>0) GoDirection(1);
        while(cur.y>y) GoDirection(3);
        while(cur.y<y) GoDirection(4);
        while(cur.x<x) GoDirection(6);
    }
}
void GoDown(point q)
{
    if(q.x==target.x&&q.y==target.y) return ;
    if(q.y>0)
    {
        while(q.x<target.x)
        {
            GoDirection(5);
            GoDirection(7);
            GoDirection(1);
            q.x++;
        }
    }
    else
    {
        while(q.x<target.x)
        {
            GoDirection(7);
            GoDirection(5);
            GoDirection(1);
            GoDirection(4);
            GoDirection(0);
            GoDirection(6);
            q.x++;
        }
    }
}
void solve(point q)
{
    if(q.y==target.y)
    {
        if(cur.y==target.y&&cur.x>q.x)
        {
            GoToPoint(q.x,q.y);
            q.x++;
        }
        else if(q.x==0)
             {
                 GoToPoint(0,q.y-1);
                 GoDirection(7);
                 GoDirection(1);
                 q.x++;
             }
             else GoToPoint(q.x-1,q.y);
        GoDown(q);
    }
    else
    {
        if(q.x>0)
        {
            if(q.y==cur.y&&cur.x>q.x) GoToPoint(q.x+1,q.y);
            else
            {
                GoToPoint(q.x,q.y);
                q.x--;
            }
            while(q.x>0)
            {
                if(q.y>0)
                {
                    GoDirection(0);
                    GoDirection(2);
                    GoDirection(6);
                }
                else
                {
                    GoDirection(2);
                    GoDirection(0);
                    GoDirection(6);
                    GoDirection(4);
                    GoDirection(5);
                    GoDirection(1);
                }
                q.x--;
            }
        }
        if(cur.y<q.y) GoToPoint(0,q.y-1);
        else if(cur.y==q.y)
             {
                 GoToPoint(1,q.y);
                 GoDirection(2);
                 GoDirection(3);
                 q.y++;
             }
             else
             {
                 GoToPoint(0,q.y);
                 q.y++;
             }
        while(q.y<target.y)
        {
            GoDirection(7);
            GoDirection(2);
            GoDirection(3);
            q.y++;
        }
        if(q.x==target.x) return ;
        GoDirection(7);
        GoDirection(1);
        q.x++;
        GoDown(q);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int c[1005];
    memset(c,0,sizeof(c));
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
            c[a[i][j]]++;
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&b[i][j]);
            c[b[i][j]]--;
        }
    for(int i=1;i<=900;i++) if(c[i]!=0) {printf("-1\n");return 0;}
    if(n==1||m==1)
    {
        if(check(a))
        {
            printf("2\n");
            if(n==1) printf("1 1\n1 2\n1 1\n");
            else printf("1 1\n2 1\n1 1\n");
            return 0;
        }
        int c[40][40];
        bool ok=false;
        if(n==1)
        {
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[0][j],c[0][j+1]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i+1;j<m;j++)
                {
                    swap(c[0][j-1],c[0][j]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[j][0],c[j+1][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i+1;j<n;j++)
                {
                    swap(c[j-1][0],c[j][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
    }
    else
    {
        cnt=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]==b[0][0])
                {
                    cur=point(i,j);
                    break;
                }
            }
            if(cur.x>=0) break;
        }
        p[cnt++]=cur;
        target=point(n-1,m-1);
        while(1)
        {
            if(a[target.x][target.y]!=b[target.x][target.y]||(target.x==cur.x&&target.y==cur.y)) solve(Find());
            target.x--;
            if(target.x==-1)
            {
                target.x=n-1;
                target.y--;
            }
            if(target.y==0&&target.x==0) break;
        }
        output();
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int n,m,cnt,a[33][33],b[33][33];
struct point
{
    int x,y;
    point(int _x=-1,int _y=-1) {x=_x;y=_y;}
}p[1000005],target,cur;
bool check(int a[33][33])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) if(a[i][j]!=b[i][j]) return false;
    return true;
}
void output()
{
    printf("%d\n",cnt-1);
    for(int i=0;i<cnt;i++) printf("%d %d\n",p[i].x+1,p[i].y+1);
}
point GetNext(point p)
{
    point q=p;
    q.x--;
    if(q.x==-1)
    {
        q.x=n-1;
        q.y--;
    }
    return q;
}
void GoDirection(int k)
{
    int dx=cur.x+d[k][0],dy=cur.y+d[k][1];
    swap(a[dx][dy],a[cur.x][cur.y]);
    cur=point(dx,dy);
    p[cnt++]=point(dx,dy);
}
bool Find(point &ans)
{
    int val=b[target.x][target.y];
    for(int i=target.x-1;i>=0;i--)
    {
        if(i==cur.x&&target.y==cur.y) continue;
        if(a[i][target.y]==val) {ans=point(i,target.y);return true;}
    }
    for(int j=target.y-1;j>=0;j--)
        for(int i=n-1;i>=0;i--)
        {
            if(i==cur.x&&j==cur.y) continue;
            if(a[i][j]==val) {ans=point(i,j);return true;}
        }
    return false;
}
void GoToPoint(int x,int y)
{
    if(cur.x==x&&cur.y==y) return ;
    if(cur.y==y)
    {
        while(cur.x<x) GoDirection(6);
        while(cur.x>x) GoDirection(1);
    }
    else
    {
        while(cur.x>0) GoDirection(1);
        while(cur.y>y) GoDirection(3);
        while(cur.y<y) GoDirection(4);
        while(cur.x<x) GoDirection(6);
    }
}
void GoDown(point q)
{
    if(q.x==target.x&&q.y==target.y) return ;
    if(q.y)
    {
        while(q.x<target.x)
        {
            GoDirection(5);
            GoDirection(7);
            GoDirection(1);
            q.x++;
        }
    }
    else
    {
        while(q.x<target.x)
        {
            GoDirection(7);
            GoDirection(5);
            GoDirection(1);
            GoDirection(4);
            GoDirection(0);
            GoDirection(6);
            q.x++;
        }
    }
}
void solve(point q)
{
    if(q.y==target.y)
    {
        if(cur.y==target.y&&cur.x>q.x)
        {
            GoToPoint(q.x,q.y);
            q.x++;
        }
        else if(q.x==0)
             {
                 GoToPoint(0,q.y-1);
                 GoDirection(7);
                 GoDirection(1);
                 q.x++;
             }
             else GoToPoint(q.x-1,q.y);
        GoDown(q);
    }
    else
    {
        if(q.x!=0)
        {
            if(q.y==cur.y&&cur.x>q.x) GoToPoint(q.x+1,q.y);
            else
            {
                GoToPoint(q.x,q.y);
                q.x--;
            }
            while(q.x>0)
            {
                if(q.y)
                {
                    GoDirection(0);
                    GoDirection(2);
                    GoDirection(6);
                }
                else
                {
                    GoDirection(2);
                    GoDirection(0);
                    GoDirection(6);
                    GoDirection(4);
                    GoDirection(5);
                    GoDirection(1);
                }
                q.x--;
            }
        }
        if(cur.y<q.y) GoToPoint(0,q.y-1);
        else if(cur.y==q.y)
             {
                 GoToPoint(1,q.y);
                 GoDirection(2);
                 GoDirection(3);
                 q.y++;
             }
             else
             {
                 GoToPoint(0,q.y);
                 q.y++;
             }
        while(q.y<target.y)
        {
            GoDirection(7);
            GoDirection(2);
            GoDirection(3);
            q.y++;
        }
        if(q.x==target.x) return ;
        GoDirection(7);
        GoDirection(1);
        q.x++;
        GoDown(q);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) scanf("%d",&a[i][j]);
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) scanf("%d",&b[i][j]);
    if(n==1||m==1)
    {
        if(check(a))
        {
            printf("2\n");
            if(n==1) printf("1 1\n1 2\n1 1\n");
            else printf("1 1\n2 1\n1 1\n");
            return 0;
        }
        int c[33][33];
        bool ok=false;
        if(n==1)
        {
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[0][j],c[0][j+1]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i+1;j<m;j++)
                {
                    swap(c[0][j-1],c[0][j]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[j][0],c[j+1][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i+1;j<n;j++)
                {
                    swap(c[j-1][0],c[j][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
    }
    else
    {
        cnt=0;
        cur=point(-1,-1);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]==b[0][0])
                {
                    cur=point(i,j);
                    break;
                }
            }
            if(cur.x>=0) break;
        }
        if(cur.x==-1) {printf("-1\n");return 0;}
        p[cnt++]=cur;
        target=point(n-1,m-1);
        while(1)
        {
            if(a[target.x][target.y]!=b[target.x][target.y])
            {
                point tp;
                if(!Find(tp)) {printf("-1\n");return 0;}
                solve(tp);
            }
            target=GetNext(target);
            if(target.y<0) break;
        }
        output();
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int n,m,cnt,a[33][33],b[33][33];
struct point
{
    int x,y;
    point(int _x=-1,int _y=-1) {x=_x;y=_y;}
}p[1000005],target,cur;
bool check(int a[33][33])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) if(a[i][j]!=b[i][j]) return false;
    return true;
}
void output()
{
    printf("%d\n",cnt-1);
    for(int i=0;i<cnt;i++) printf("%d %d\n",p[i].x+1,p[i].y+1);
}
inline void GoDirection(int k)
{
    int dx=cur.x+d[k][0],dy=cur.y+d[k][1];
    swap(a[dx][dy],a[cur.x][cur.y]);
    cur=point(dx,dy);
    p[cnt++]=point(dx,dy);
}
point Find()
{
    int val=b[target.x][target.y];
    for(int i=target.x-1;i>=0;i--)
    {
        if(i==cur.x&&target.y==cur.y) continue;
        if(a[i][target.y]==val) return point(i,target.y);
    }
    for(int j=target.y-1;j>=0;j--)
        for(int i=n-1;i>=0;i--)
        {
            if(i==cur.x&&j==cur.y) continue;
            if(a[i][j]==val) return point(i,j);
        }
}
void GoToPoint(int x,int y)
{
    if(y<0) printf("FUCK1\n");
    if(cur.x==x&&cur.y==y) return ;
    if(cur.y==y)
    {
        while(cur.x<x) GoDirection(6);
        while(cur.x>x) GoDirection(1);
    }
    else
    {
        while(cur.x>0) GoDirection(1);
        while(cur.y>y) GoDirection(3);
        while(cur.y<y) GoDirection(4);
        while(cur.x<x) GoDirection(6);
    }
}
void GoDown(point q)
{
    if(q.x==target.x&&q.y==target.y) return ;
    if(q.y>0)
    {
        while(q.x<target.x)
        {
            GoDirection(5);
            GoDirection(7);
            GoDirection(1);
            q.x++;
        }
    }
    else
    {
        while(q.x<target.x)
        {
            GoDirection(7);
            GoDirection(5);
            GoDirection(1);
            GoDirection(4);
            GoDirection(0);
            GoDirection(6);
            if(cur.y<0) printf("FUCK2\n");
            q.x++;
        }
    }
}
void solve(point q)
{
    if(q.x==cur.x&&q.y==cur.y) printf("FUCK4\n");
    if(q.y==target.y)
    {
        if(cur.y==target.y&&cur.x>q.x)
        {
            GoToPoint(q.x,q.y);
            q.x++;
        }
        else if(q.x==0)
             {
                 if(q.y==0) printf("FUCK3\n");
                 GoToPoint(0,q.y-1);
                 GoDirection(7);
                 GoDirection(1);
                 q.x++;
             }
             else GoToPoint(q.x-1,q.y);
        GoDown(q);
    }
    else
    {
        if(q.x>0)
        {
            if(q.y==cur.y&&cur.x>q.x) GoToPoint(q.x+1,q.y);
            else
            {
                GoToPoint(q.x,q.y);
                q.x--;
            }
            while(q.x>0)
            {
                if(q.y>0)
                {
                    GoDirection(0);
                    GoDirection(2);
                    GoDirection(6);
                }
                else
                {
                    GoDirection(2);
                    GoDirection(0);
                    GoDirection(6);
                    GoDirection(4);
                    GoDirection(5);
                    GoDirection(1);
                }
                q.x--;
            }
        }
        if(cur.y<q.y)
        {
            if(q.y==0) printf("FUCK5\n");
            GoToPoint(0,q.y-1);
        }
        else if(cur.y==q.y)
             {
                 GoToPoint(1,q.y);
                 GoDirection(2);
                 GoDirection(3);
                 q.y++;
             }
             else
             {
                 GoToPoint(0,q.y);
                 q.y++;
             }
        while(q.y<target.y)
        {
            GoDirection(7);
            GoDirection(2);
            GoDirection(3);
            q.y++;
        }
        if(q.x==target.x) return ;
        GoDirection(7);
        GoDirection(1);
        q.x++;
        GoDown(q);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int c[1005];
    memset(c,0,sizeof(c));
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
            c[a[i][j]]++;
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&b[i][j]);
            c[b[i][j]]--;
        }
    for(int i=1;i<=900;i++) if(c[i]!=0) {printf("-1\n");return 0;}
    if(n==1||m==1)
    {
        if(check(a))
        {
            printf("2\n");
            if(n==1) printf("1 1\n1 2\n1 1\n");
            else printf("1 1\n2 1\n1 1\n");
            return 0;
        }
        int c[33][33];
        bool ok=false;
        if(n==1)
        {
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[0][j],c[0][j+1]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i+1;j<m;j++)
                {
                    swap(c[0][j-1],c[0][j]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[j][0],c[j+1][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i+1;j<n;j++)
                {
                    swap(c[j-1][0],c[j][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
    }
    else
    {
        cnt=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]==b[0][0])
                {
                    cur=point(i,j);
                    break;
                }
            }
            if(cur.x>=0) break;
        }
        p[cnt++]=cur;
        target=point(n-1,m-1);
        while(1)
        {
            if(a[target.x][target.y]!=b[target.x][target.y]) solve(Find());
            target.x--;
            if(target.x==-1)
            {
                target.x=n-1;
                target.y--;
            }
            if(target.y<0||target.x<0) break;
        }
        output();
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int n,m,cnt,a[33][33],b[33][33];
struct point
{
    int x,y;
    point(int _x=-1,int _y=-1) {x=_x;y=_y;}
}p[1000005],target,cur;
bool check(int a[33][33])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) if(a[i][j]!=b[i][j]) return false;
    return true;
}
void output()
{
    printf("%d\n",cnt-1);
    for(int i=0;i<cnt;i++) printf("%d %d\n",p[i].x+1,p[i].y+1);
}
point GetNext(point p)
{
    point q=p;
    q.x--;
    if(q.x==-1)
    {
        q.x=n-1;
        q.y--;
    }
    return q;
}
void GoDirection(int k)
{
    int dx=cur.x+d[k][0],dy=cur.y+d[k][1];
    swap(a[dx][dy],a[cur.x][cur.y]);
    cur=point(dx,dy);
    p[cnt++]=point(dx,dy);
}
point Find()
{
    int val=b[target.x][target.y];
    for(int i=target.x-1;i>=0;i--)
    {
        if(i==cur.x&&target.y==cur.y) continue;
        if(a[i][target.y]==val) return point(i,target.y);
    }
    for(int j=target.y-1;j>=0;j--)
        for(int i=n-1;i>=0;i--)
        {
            if(i==cur.x&&j==cur.y) continue;
            if(a[i][j]==val) return point(i,j);
        }
}
void GoToPoint(int x,int y)
{
    if(cur.x==x&&cur.y==y) return ;
    if(cur.y==y)
    {
        while(cur.x<x) GoDirection(6);
        while(cur.x>x) GoDirection(1);
    }
    else
    {
        while(cur.x>0) GoDirection(1);
        while(cur.y>y) GoDirection(3);
        while(cur.y<y) GoDirection(4);
        while(cur.x<x) GoDirection(6);
    }
}
void GoDown(point q)
{
    if(q.x==target.x&&q.y==target.y) return ;
    if(q.y)
    {
        while(q.x<target.x)
        {
            GoDirection(5);
            GoDirection(7);
            GoDirection(1);
            q.x++;
        }
    }
    else
    {
        while(q.x<target.x)
        {
            GoDirection(7);
            GoDirection(5);
            GoDirection(1);
            GoDirection(4);
            GoDirection(0);
            GoDirection(6);
            q.x++;
        }
    }
}
void solve(point q)
{
    if(q.y==target.y)
    {
        if(cur.y==target.y&&cur.x>q.x)
        {
            GoToPoint(q.x,q.y);
            q.x++;
        }
        else if(q.x==0)
             {
                 GoToPoint(0,q.y-1);
                 GoDirection(7);
                 GoDirection(1);
                 q.x++;
             }
             else GoToPoint(q.x-1,q.y);
        GoDown(q);
    }
    else
    {
        if(q.x!=0)
        {
            if(q.y==cur.y&&cur.x>q.x) GoToPoint(q.x+1,q.y);
            else
            {
                GoToPoint(q.x,q.y);
                q.x--;
            }
            while(q.x>0)
            {
                if(q.y)
                {
                    GoDirection(0);
                    GoDirection(2);
                    GoDirection(6);
                }
                else
                {
                    GoDirection(2);
                    GoDirection(0);
                    GoDirection(6);
                    GoDirection(4);
                    GoDirection(5);
                    GoDirection(1);
                }
                q.x--;
            }
        }
        if(cur.y<q.y) GoToPoint(0,q.y-1);
        else if(cur.y==q.y)
             {
                 GoToPoint(1,q.y);
                 GoDirection(2);
                 GoDirection(3);
                 q.y++;
             }
             else
             {
                 GoToPoint(0,q.y);
                 q.y++;
             }
        while(q.y<target.y)
        {
            GoDirection(7);
            GoDirection(2);
            GoDirection(3);
            q.y++;
        }
        if(q.x==target.x) return ;
        GoDirection(7);
        GoDirection(1);
        q.x++;
        GoDown(q);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int c[1005];
    memset(c,0,sizeof(c));
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
            c[a[i][j]]++;
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf("%d",&b[i][j]);
            c[b[i][j]]--;
        }
    for(int i=1;i<=900;i++) if(c[i]!=0) {printf("-1\n");return 0;}
    if(n==1||m==1)
    {
        if(check(a))
        {
            printf("2\n");
            if(n==1) printf("1 1\n1 2\n1 1\n");
            else printf("1 1\n2 1\n1 1\n");
            return 0;
        }
        int c[33][33];
        bool ok=false;
        if(n==1)
        {
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[0][j],c[0][j+1]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<m;i++)
            {
                cnt=0;
                p[cnt++]=point(0,i);
                for(int j=0;j<m;j++) c[0][j]=a[0][j];
                for(int j=i+1;j<m;j++)
                {
                    swap(c[0][j-1],c[0][j]);
                    p[cnt++]=point(0,j);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
        else
        {
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i-1;j>=0;j--)
                {
                    swap(c[j][0],c[j+1][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) {output();return 0;}
            for(int i=0;i<n;i++)
            {
                cnt=0;
                p[cnt++]=point(i,0);
                for(int j=0;j<n;j++) c[j][0]=a[j][0];
                for(int j=i+1;j<n;j++)
                {
                    swap(c[j-1][0],c[j][0]);
                    p[cnt++]=point(j,0);
                    if(check(c)) {ok=true;break;}
                }
                if(ok) break;
            }
            if(ok) output();
            else printf("-1\n");
        }
    }
    else
    {

        cnt=0;
        cur=point(-1,-1);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]==b[0][0])
                {
                    cur=point(i,j);
                    break;
                }
            }
            if(cur.x>=0) break;
        }
        p[cnt++]=cur;
        target=point(n-1,m-1);
        while(1)
        {
            if(a[target.x][target.y]!=b[target.x][target.y]) solve(Find());
            target=GetNext(target);
            if(target.y<0) break;
        }
        output();
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <cstdlib>

using namespace std;

int n,m;
int x[100][100];
int y[100][100];
int iact=-1,jact=-1;

int movi[]={-1,-1,-1,0,0,1,1,1};
int movj[]={-1,0,1,-1,1,-1,0,1};

vector<pair<int,int> > sol;

void insertasol()
{
  sol.push_back(pair<int,int> (iact,jact));
}

int absolut(int x)
{
  if (x<0) return -x;
  return x;
}

pair<int,int> distancia(int i1,int j1,int i2,int j2)
{
  return pair<int,int> (max(absolut(i1-i2),absolut(j1-j2)),
			absolut(i1-i2)+absolut(j1-j2));
}

void siguiente(int i,int j,int &inext,int &jnext,int ifin,int jfin)
{
  pair<int,int> minimo(1000000000,0);
  for (int k=0;k<8;k++) {
    int ii=i+movi[k];
    int jj=j+movj[k];
    if (x[ii][jj] and distancia(ii,jj,ifin,jfin)<minimo) {
      minimo=distancia(ii,jj,ifin,jfin);
      inext=ii;
      jnext=jj;
    }
  }
}

void buscavalor(int &i,int &j,int val)
{
  for (i=1;i<=n;i++)
    for (j=1;j<=m;j++)
      if (not (i==iact and j==jact) and x[i][j]==val)
	return;
}

void elimina(int ifin,int jfin)
{
  int iini,jini;
  buscavalor(iini,jini,y[ifin][jfin]);
  x[iini][jini]=0;
  while (not (iini==ifin and jini==jfin)) {
    int nextiini,nextjini;
    siguiente(iini,jini,nextiini,nextjini,ifin,jfin);
    while (not (iact==nextiini and jact==nextjini)) {
      int nextiact,nextjact;
      siguiente(iact,jact,nextiact,nextjact,nextiini,nextjini);
      swap(x[iact][jact],x[nextiact][nextjact]);
      iact=nextiact;
      jact=nextjact;
      insertasol();
    }
    swap(x[iact][jact],x[iini][jini]);
    swap(iact,iini);
    swap(jact,jini);
    insertasol();
  }
}

int main()
{
  cin>>n>>m;
  multiset<int> sx;
  for (int i=1;i<=n;i++) {
    for (int j=1;j<=m;j++) {
      cin>>x[i][j];
      sx.insert(x[i][j]);
    }
  }
  multiset<int> sy;
  for (int i=1;i<=n;i++) {
    for (int j=1;j<=m;j++) {
      cin>>y[i][j];
      sy.insert(y[i][j]);
    }
  }
  if (not (sx==sy)) {
    cout<<-1<<endl;
    exit(0);
  }
  if (n==1) {
    int j1=1;
    while (x[1][j1]==y[1][j1]) j1++;
    int j2=m;
    while (x[1][j2]==y[1][j2]) j2--;
    {
      vector<int> vx,vy;
      for (int j=j1+1;j<=j2;j++) vx.push_back(x[1][j]);
      for (int j=j1;j<=j2-1;j++) vy.push_back(y[1][j]);
      if (vx==vy and x[1][j1]==y[1][j2]) {
	cout<<j2-j1<<endl;
	cout<<1<<" "<<j1<<endl;
	for (int j=j1+1;j<=j2;j++)
	  cout<<1<<" "<<j<<endl;
	exit(0);
      }
    }
    {
      vector<int> vx,vy;
      for (int j=j1;j<=j2-1;j++) vx.push_back(x[1][j]);
      for (int j=j1+1;j<=j2;j++) vy.push_back(y[1][j]);
      if (vx==vy and y[1][j1]==x[1][j2]) {
	cout<<j2-j1<<endl;
	cout<<1<<" "<<j2<<endl;
	for (int j=j2-1;j>=j1;j--)
	  cout<<1<<" "<<j<<endl;
	exit(0);
      }
    }
    cout<<-1<<endl;
    exit(0);
  } else if (m==1) {
    int i1=1;
    while (x[i1][1]==y[i1][1]) i1++;
    int i2=n;
    while (x[i2][1]==y[i2][1]) i2--;
    {
      vector<int> vx,vy;
      for (int i=i1+1;i<=i2;i++) vx.push_back(x[i][1]);
      for (int i=i1;i<=i2-1;i++) vy.push_back(y[i][1]);
      if (vx==vy and x[i1][1]==y[i2][1]) {
	cout<<i2-i1<<endl;
	cout<<i1<<" "<<1<<endl;
	for (int i=i1+1;i<=i2;i++)
	  cout<<i<<" "<<1<<endl;
	exit(0);
      }
    }
    {
      vector<int> vx,vy;
      for (int i=i1;i<=i2-1;i++) vx.push_back(x[i][1]);
      for (int i=i1+1;i<=i2;i++) vy.push_back(y[i][1]);
      if (vx==vy and y[i1][1]==x[i2][1]) {
	cout<<i2-i1<<endl;
	cout<<i2<<" "<<1<<endl;
	for (int i=i2-1;i>=i1;i--)
	  cout<<i<<" "<<1<<endl;
	exit(0);
      }
    }
    cout<<-1<<endl;
    exit(0);
  }
  int iaux,jaux;
  buscavalor(iaux,jaux,y[1][1]);
  iact=iaux;
  jact=jaux;
  insertasol();
  for (int i=n;i>=3;i--)
    for (int j=m;j>=1;j--)
      elimina(i,j);
  for (int j=m;j>=3;j--) {
    elimina(2,j);
    elimina(1,j);
  }
  if (not (iact==2 and jact==2)) {
    swap(x[iact][jact],x[2][2]);
    iact=2;
    jact=2;
    insertasol();
  }
  if (x[1][1]==y[iact][jact]) {
    swap(x[1][1],x[iact][jact]);
    iact=1;
    jact=1;
    insertasol();
  } else if (x[2][1]==y[iact][jact]) {
    swap(x[2][1],x[iact][jact]);
    iact=2;
    jact=1;
    insertasol();
  } else {
    swap(x[1][2],x[iact][jact]);
    iact=1;
    jact=2;
    insertasol();
  }
  if (not (iact==1 and jact==2)) {
    swap(x[iact][jact],x[1][2]);
    iact=1;
    jact=2;
    insertasol();
  }
  if (x[1][1]==y[iact][jact]) {
    swap(x[1][1],x[iact][jact]);
    iact=1;
    jact=1;
    insertasol();
  } else {
    swap(x[2][1],x[iact][jact]);
    iact=2;
    jact=1;
    insertasol();
  }
  if (not (iact==1 and jact==1)) {
    swap(x[iact][jact],x[1][1]);
    iact=1;
    jact=1;
    insertasol();
  }
  cout<<int(sol.size())-1<<endl;
  for (int i=0;i<int(sol.size());i++)
    cout<<sol[i].first<<" "<<sol[i].second<<endl;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	if (p == cursor) return ;
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

void colMove(Pos &where, Pos target) {
	assert(cursor == Pos(n - 2, m - 1));
	if (where.row == n - 1) {
		run(Pos(where.row - 1, where.col));
		while (where.col != target.col) {
			if (where.col > target.col) step(Pos(where.row, where.col - 1));
			if (where.col < target.col) step(Pos(where.row, where.col + 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			if (where.col > target.col) where.col--; else where.col++;
			step(Pos(where.row - 1, where.col));
		}
	} else {
		if (where.row == cursor.row) run(Pos(n - 1, m - 1));
		run(Pos(where.row + 1, where.col));
		while (where.col != target.col) {
			if (where.col > target.col) step(Pos(where.row, where.col - 1));
			if (where.col < target.col) step(Pos(where.row, where.col + 1));
			step(where);
			step(Pos(where.row + 1, where.col));
			if (where.col > target.col) where.col--; else where.col++;
			step(Pos(where.row + 1, where.col));
		}
	}
}

void rowMove(Pos &where, Pos target) {
	if (where.row == target.row) return ;
	while (where.row > target.row) {
		if (where.col < m - 1) {
			step(Pos(where.row, where.col + 1));
		} else {
			step(Pos(where.row, where.col - 1));
		}
		Pos bak = cursor;
		step(Pos(where.row - 1, where.col));
		step(where);
		step(bak);
		where.row--;
	}
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}

	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	run(Pos(n - 2, m - 1));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			Pos where = find(t[i][j]);
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			// printf("i = %d j = %d\n", i, j);
			//
			// printf("cursor = %d %d\n", cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}
			// puts("");
			colMove(where, Pos(where.row, j));
			//
			// printf("cursor = %d %d\n", cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}
			// puts("");
			rowMove(where, Pos(i, j));
			cursor.show();
			run(Pos(n - 2, m - 1));
			// printf("cursor = %d %d\n", cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}
			// puts("");
			locked[i][j] = true;
			assert(s[i][j] == t[i][j]);
		}
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.row == n - 1) {
					step(Pos(n - 2, m - 1));
					run(Pos(where.row - 1, where.col));
					while (where.col != j) {
						if (where.col > j) step(Pos(where.row, where.col - 1));
						if (where.col < j) step(Pos(where.row, where.col + 1));
						step(where);
						step(Pos(where.row - 1, where.col));
						if (where.col > j) where.col--; else where.col++;
						step(Pos(where.row - 1, where.col));
					}
				} else {
					run(Pos(where.row + 1, where.col));
					while (where.col != j) {
						if (where.col > j) step(Pos(where.row, where.col - 1));
						if (where.col < j) step(Pos(where.row, where.col + 1));
						step(where);
						step(Pos(where.row + 1, where.col));
						if (where.col > j) where.col--; else where.col++;
						step(Pos(where.row + 1, where.col));
					}
				}

				step(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col - 1));
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}
			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	// n = 30, m = 30;
	// for (int i = 0, t1 = 0, t2 = 30 * 30 - 1; i < n; i++) {
	// 	for (int j = 0; j < m; j++) {
	// 		s[i][j] = t1++;
	// 		t[i][j] = t2--;
	// 	}
	// }

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col));
				step(Pos(cursor.row, cursor.col - 1));

				while (where.col > j) {
					step(Pos(where.row, where.col - 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col--;
					step(Pos(cursor.row, cursor.col - 1));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			//assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			//assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				//assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col));
				step(Pos(cursor.row, cursor.col - 1));

				while (where.col > j) {
					step(Pos(where.row, where.col - 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col--;
					step(Pos(cursor.row, cursor.col - 1));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			//assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col));
				step(Pos(cursor.row, cursor.col - 1));

				while (where.col > j) {
					step(Pos(where.row, where.col - 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col--;
					step(Pos(cursor.row, cursor.col - 1));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;

	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			if (where == Pos(-1, -1)) return false;
			if (where.col == m - 1) {
				run(Pos(where.row, where.col - 1));
				step(where);
				where.col--;
			}

			assert(where.col < m - 1);
			run(Pos(where.row, where.col + 1));
			while (where.row > i) {
				step(Pos(where.row - 1, where.col));
				step(where);
				step(Pos(where.row, where.col + 1));
				where.row--;
				step(Pos(where.row, where.col + 1));
			}
			step(Pos(cursor.row + 1, cursor.col));
			step(Pos(cursor.row, cursor.col - 1));

			while (where.col > j) {
				step(Pos(where.row, where.col - 1));
				step(where);
				step(Pos(where.row + 1, where.col));
				where.col--;
				step(Pos(cursor.row, cursor.col - 1));
			}
			locked[i][j] = true;
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col - 1));

				while (where.col != j) {
					if (where.col > j) step(Pos(where.row, where.col - 1));
					if (where.col < j) step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					if (where.col > j) where.col--; else where.col++;
					step(Pos(where.row + 1, where.col));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.row == n - 1) {
					step(Pos(n - 2, m - 1));
					run(Pos(where.row - 1, where.col));
					while (where.col != j) {
						if (where.col > j) step(Pos(where.row, where.col - 1));
						if (where.col < j) step(Pos(where.row, where.col + 1));
						step(where);
						step(Pos(where.row - 1, where.col));
						if (where.col > j) where.col--; else where.col++;
						step(Pos(where.row - 1, where.col));
					}
				} else {
					run(Pos(where.row + 1, where.col));
					while (where.col != j) {
						if (where.col > j) step(Pos(where.row, where.col - 1));
						if (where.col < j) step(Pos(where.row, where.col + 1));
						step(where);
						step(Pos(where.row + 1, where.col));
						if (where.col > j) where.col--; else where.col++;
						step(Pos(where.row + 1, where.col));
					}
				}

				step(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col - 1));
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}
			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	n = 30, m = 30;
	for (int i = 0, t1 = 0, t2 = 30 * 30 - 1; i < n; i++) {
		for (int j = 0; j < m; j++) {
			s[i][j] = t1++;
			t[i][j] = t2--;
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			//std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col));
				step(Pos(cursor.row, cursor.col - 1));

				while (where.col > j) {
					step(Pos(where.row, where.col - 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col--;
					step(Pos(cursor.row, cursor.col - 1));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;

	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			if (where == Pos(-1, -1)) return false;
			if (where.col == m - 1) {
				run(Pos(where.row, where.col - 1));
				step(where);
				where.col--;
			}

			assert(where.col < m - 1);
			run(Pos(where.row, where.col + 1));
			while (where.row > i) {
				step(Pos(where.row - 1, where.col));
				step(where);
				step(Pos(where.row, where.col + 1));
				where.row--;
				step(Pos(where.row, where.col + 1));
			}
			step(Pos(cursor.row + 1, cursor.col));
			step(Pos(cursor.row, cursor.col - 1));

			while (where.col > j) {
				step(Pos(where.row, where.col - 1));
				step(where);
				step(Pos(where.row + 1, where.col));
				where.col--;
				step(Pos(cursor.row, cursor.col - 1));
			}
			locked[i][j] = true;
		}
	}
	// for (int i = 0; i < n; i++, puts(""))
	// 	for (int j = 0; j < m; j++) {
	// 		printf("%d ", s[i][j]);
	// 	}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size());
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			std::cout << s[i][j] << " vs " << t[i][j] << std::endl;
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			if (j == m - 1) {
				if (where.row == n - 1) {
					step(Pos(cursor.row - 1, cursor.col));
					run(Pos(where.row - 1, where.col));
					step(where);
					where.row--;
				}
				run(Pos(where.row + 1, where.col));
				while (where.col < m - 1) {
					step(Pos(where.row, where.col + 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col++;
					step(Pos(where.row + 1, where.col));
				}
				while (where.row > i) {
					run(Pos(where.row, where.col - 1));
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col - 1));
					where.row--;
				}
			} else {
				if (where.col == m - 1) {
					run(Pos(where.row, where.col - 1));
					step(where);
					where.col--;
				}

				assert(where.col < m - 1);
				run(Pos(where.row, where.col + 1));
				while (where.row > i) {
					step(Pos(where.row - 1, where.col));
					step(where);
					step(Pos(where.row, where.col + 1));
					where.row--;
					step(Pos(where.row, where.col + 1));
				}
				step(Pos(cursor.row + 1, cursor.col));
				step(Pos(cursor.row, cursor.col - 1));

				while (where.col > j) {
					step(Pos(where.row, where.col - 1));
					step(where);
					step(Pos(where.row + 1, where.col));
					where.col--;
					step(Pos(cursor.row, cursor.col - 1));
				}
			}
			locked[i][j] = true;
			// printf("i = %d j = %d cursor = %d %d\n", i, j, cursor.row, cursor.col);
			// for (int i = 0; i < n; i++, puts(""))
			// 	for (int j = 0; j < m; j++) {
			// 		printf("%d ", s[i][j]);
			// 	}

			assert(s[i][j] == t[i][j]);
		}
	}
	for (int i = 0; i < n; i++, puts(""))
		for (int j = 0; j < m; j++) {
			printf("%d ", s[i][j]);
		}

	locked[n - 2][m - 1] = true;
	for (int i = n - 1, j = 0; j < m; j++) {
		run(Pos(n - 2, m - 1));
		Pos where = find(t[i][j]);
		if (where == Pos(-1, -1)) return false;
		while (cursor.col > where.col) step(Pos(cursor.row, cursor.col - 1));
		while (where.col > j) {
			step(Pos(where.row, where.col - 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			where.col--;
			step(Pos(cursor.row, cursor.col - 1));
		}
		locked[i][j] = 1;
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cassert>
#include <vector>
#include <iostream>

const int N = 33;

int n, m;
int s[N][N], t[N][N];

struct Pos {
	int row, col;
	Pos(int row, int col) : row(row), col(col) {}
	Pos() {}
	void show() {
		printf("%d %d\n", row + 1, col + 1);
	}
	friend inline bool operator == (const auto &a, const auto &b) {
		return a.row == b.row && a.col == b.col;
	}
};

std::vector<Pos > answer;
Pos cursor;
bool locked[N][N];

Pos find(int color) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (!locked[i][j] && s[i][j] == color && !(Pos(i, j) == cursor)) {
				return Pos(i, j);
			}
		}
	}
	return Pos(-1, -1);
}

void step(Pos p) {
	if (p == cursor) return ;
	answer.push_back(p);
	assert(std::max(std::abs(p.row - cursor.row), std::abs(p.col - cursor.col)) <= 1);
	std::swap(s[cursor.row][cursor.col], s[p.row][p.col]);
	cursor = p;
}

void run(Pos target) {
	while (cursor.col < target.col) step(Pos(cursor.row, cursor.col + 1));
	while (cursor.col > target.col) step(Pos(cursor.row, cursor.col - 1));
	while (cursor.row > target.row) step(Pos(cursor.row - 1, cursor.col));
	while (cursor.row < target.row) step(Pos(cursor.row + 1, cursor.col));
}

void colMove(Pos &where, Pos target) {
	assert(cursor == Pos(n - 1, m - 1));
	if (where.row == n - 1) {
		step(Pos(n - 2, m - 1));
		run(Pos(where.row - 1, where.col));
		while (where.col != target.col) {
			if (where.col > target.col) step(Pos(where.row, where.col - 1));
			if (where.col < target.col) step(Pos(where.row, where.col + 1));
			step(where);
			step(Pos(where.row - 1, where.col));
			if (where.col > target.col) where.col--; else where.col++;
			step(Pos(where.row - 1, where.col));
		}
	} else {
		run(Pos(where.row + 1, where.col));
		while (where.col != target.col) {
			if (where.col > target.col) step(Pos(where.row, where.col - 1));
			if (where.col < target.col) step(Pos(where.row, where.col + 1));
			step(where);
			step(Pos(where.row + 1, where.col));
			if (where.col > target.col) where.col--; else where.col++;
			step(Pos(where.row + 1, where.col));
		}
	}
}

void rowMove(Pos &where, Pos target) {
	if (where.row == target.row) return ;
	while (where.row > target.row) {
		if (where.col < m - 1) {
			step(Pos(where.row, where.col + 1));
		} else {
			step(Pos(where.row, where.col - 1));
		}
		Pos bak = cursor;
		step(Pos(where.row - 1, where.col));
		step(where);
		step(bak);
		where.row--;
	}
}

bool solve() {
	answer.clear();
	if (n == 1) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				if (s[0][i] != t[0][j]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < m; k++) {
					if (k != i) sv.push_back(s[0][k]);
					if (k != j) tv.push_back(t[0][k]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(0, i));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row, cursor.col + 1));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row, cursor.col - 1));
					}
					return true;
				}
			}
		}
		return false;
	} else if (m == 1) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (s[i][0] != t[j][0]) continue;
				std::vector<int > sv, tv;
				for (int k = 0; k < n; k++) {
					if (k != i) sv.push_back(s[k][0]);
					if (k != j) tv.push_back(t[k][0]);
				}
				if (sv == tv) {
					answer.push_back(cursor = Pos(i, 0));
					if (i < j) {
						for (int k = i; k < j; k++) step(Pos(cursor.row + 1, cursor.col));
					} else {
						for (int k = i; k > j; k--) step(Pos(cursor.row - 1, cursor.col));;
					}
					return true;
				}
			}
		}
		return false;
	}

	cursor = Pos(-1, -1);
	answer.push_back(cursor = find(t[n - 2][m - 1]));
	if (cursor == Pos(-1, -1)) return false;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (i == n - 2 && j == m - 1) continue;
			run(Pos(n - 1, m - 1));
			Pos where = find(t[i][j]);
			if (where == Pos(-1, -1)) return false;
			assert(!(where == cursor));
			colMove(where, Pos(where.row, j));
			rowMove(where, Pos(i, j));
			locked[i][j] = true;
			assert(s[i][j] == t[i][j]);
		}
	}
	return true;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &s[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf("%d", &t[i][j]);
		}
	}

	if (!solve()) {
		puts("-1");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			assert(s[i][j] == t[i][j]);
		}
	}
	printf("%d\n", answer.size() - 1);
	for (int i = 0; i < answer.size(); i++) {
		answer[i].show();
	}
	return 0;
}