#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline string tostr(const T& x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline long long parse(const string& s) {
  stringstream ss(s);
  long long x;
  ss >> x;
  return x;
}
const double EPS = 1e-9;
const int INF = 1000 * 1000 * 1000;
const char CINF = 102;
const long long LINF = INF * 1ll * INF;
const double DINF = 1e200;
const double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
int n, m;
vector<vector<int> > A, G;
vector<pair<int, int> > ans;
int a, b;
void nope() {
  cout << -1;
  exit(0);
}
void go(int aa, int bb) {
  if (make_pair(aa, bb) == make_pair(a, b) || abs(a - aa) > 1 ||
      abs(b - bb) > 1 || aa < 0 || bb < 0 || aa >= n || bb >= m) {
    cerr << "assertion failed on line " << 87 << endl;
    exit(123);
  };
  swap(A[aa][bb], A[a][b]);
  a = aa;
  b = bb;
  ans.push_back(make_pair(a, b));
}
void trans() {
  swap(n, m);
  vector<vector<int> > AA(n, vector<int>(m)), GG;
  GG = AA;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      AA[i][j] = A[j][i];
      GG[i][j] = G[j][i];
    }
  }
  for (int i = 0; i < (((int)(ans).size())); ++i) {
    swap(ans[i].first, ans[i].second);
  }
  A = AA;
  G = GG;
}
void solve() {
  if (n == 1 || m == 1) {
    bool tra = false;
    if (n > 1) {
      trans();
      tra = true;
    }
    bool f = false;
    for (int x = 0; x < (m); ++x) {
      if (f) break;
      for (int y = 0; y < (m); ++y) {
        if (f) break;
        if (x == y) continue;
        vector<int> T = A[0];
        if (y > x)
          rotate(T.begin() + x, T.begin() + x + 1, T.begin() + y + 1);
        else
          rotate(T.begin() + y, T.begin() + x, T.begin() + x + 1);
        if (T == G[0]) {
          f = true;
          a = 0;
          b = x;
          ans.push_back(make_pair(a, b));
          while (b > y) go(a, b - 1);
          while (b < y) go(a, b + 1);
        }
      }
    }
    if (!f) nope();
    if (tra) trans();
  } else {
    a = -1;
    for (int i = 0; i < n && a == -1; ++i) {
      for (int j = 0; j < m && a == -1; ++j) {
        if (A[i][j] == G[n - 1][m - 1]) a = i, b = j;
      }
    }
    if (a == -1) {
      cerr << "assertion failed on line " << 144 << endl;
      exit(123);
    };
    ans.push_back(make_pair(a, b));
    for (int r = 0; r < n - 2; ++r) {
      for (int c = 0; c < m; ++c) {
        while (b < c) go(a, b + 1);
        while (b > c) go(a, b - 1);
        while (a > r) go(a - 1, b);
        if (a < r) {
          cerr << "assertion failed on line " << 151 << endl;
          exit(123);
        };
        int aa = -1, bb = -1;
        for (int i = r; i < n && aa == -1; ++i) {
          for (int j = (i == r ? c + 1 : 0); j < m && aa == -1; ++j) {
            if (G[r][c] == A[i][j]) aa = i, bb = j;
          }
        }
        if (aa == -1) {
          cerr << "assertion failed on line " << 158 << endl;
          exit(123);
        };
        vector<pair<int, int> > tr;
        if (bb >= c && c + 1 < m) {
          go(a, b + 1);
          if (aa == r) ++aa;
          if (bb == c) ++bb;
          for (int j = c + 2; j <= bb; ++j) tr.push_back(make_pair(r, j));
          for (int i = r + 1; i <= aa; ++i) tr.push_back(make_pair(i, bb));
          for (int j = bb - 1; j >= c; --j) tr.push_back(make_pair(aa, j));
          for (int i = aa - 1; i >= r; --i) tr.push_back(make_pair(i, c));
          tr.push_back(make_pair(r, c + 1));
        } else {
          go(a + 1, b - 1);
          if (aa == r + 1) ++aa;
          if (bb == c) --bb;
          for (int j = c - 2; j >= bb; --j) tr.push_back(make_pair(r + 1, j));
          for (int i = r + 2; i <= aa; ++i) tr.push_back(make_pair(i, bb));
          for (int j = bb + 1; j <= c; ++j) tr.push_back(make_pair(aa, j));
          for (int i = aa - 1; i >= r; --i) tr.push_back(make_pair(i, c));
          tr.push_back(make_pair(r + 1, c - 1));
        }
        int it = 0;
        while (A[r][c] != G[r][c]) {
          if (it++ > 200) {
            cerr << "assertion failed on line " << 181 << endl;
            exit(123);
          };
          for (int i = 0; i < (((int)(tr).size())); ++i) {
            go(tr[i].first, tr[i].second);
          }
        }
      }
    }
    for (int c = 0; c < m - 1; ++c) {
      for (int r = n - 2; r < n; ++r) {
        while (a < r) go(a + 1, b);
        while (a > r) go(a - 1, b);
        while (b > c) go(a, b - 1);
        if (b < c) {
          cerr << "assertion failed on line " << 191 << endl;
          exit(123);
        };
        go(n - 2, c + 1);
        vector<pair<int, int> > tr;
        for (int j = c + 2; j < m; ++j) tr.push_back(make_pair(n - 2, j));
        tr.push_back(make_pair(n - 1, m - 1));
        for (int j = m - 2; j >= c; --j) tr.push_back(make_pair(n - 1, j));
        if (r == n - 2) tr.push_back(make_pair(n - 2, c));
        tr.push_back(make_pair(n - 2, c + 1));
        int it = 0;
        while (A[r][c] != G[r][c]) {
          if (make_pair(a, b) != make_pair(n - 2, c + 1)) {
            cerr << "assertion failed on line " << 201 << endl;
            exit(123);
          };
          if (it++ > 200) {
            cerr << "assertion failed on line " << 202 << endl;
            exit(123);
          };
          for (int i = 0; i < (((int)(tr).size())); ++i) {
            go(tr[i].first, tr[i].second);
          }
        }
      }
    }
    if (a != n - 1) go(n - 1, m - 1);
  }
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      if (A[i][j] != G[i][j]) {
        cerr << "assertion failed on line " << 211 << endl;
        exit(123);
      };
    }
  }
}
void stress() {
  for (n = 2; n <= 10; ++n) {
    for (m = 2; m <= 10; ++m) {
      cerr << n << ' ' << m << endl;
      for (int it = 0; it < (1000); ++it) {
        ans.clear();
        A.clear();
        A.resize(n, vector<int>(m));
        G = A;
        vector<int> P1(n * m), P2(n * m);
        for (int i = 0; i < (n * m); ++i) {
          P1[i] = P2[i] = i;
        }
        random_shuffle((P1).begin(), (P1).end());
        random_shuffle((P2).begin(), (P2).end());
        for (int i = 0; i < (n); ++i) {
          for (int j = 0; j < (m); ++j) {
            A[i][j] = P1[i * m + j];
            G[i][j] = P2[i * m + j];
          }
        }
        solve();
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  A.resize(n, vector<int>(m));
  G = A;
  multiset<int> As, Gs;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      cin >> A[i][j];
      As.insert(A[i][j]);
    }
  }
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      cin >> G[i][j];
      Gs.insert(G[i][j]);
    }
  }
  if (As != Gs) nope();
  solve();
  cout << ((int)(ans).size()) - 1 << endl;
  for (int i = 0; i < (((int)(ans).size())); ++i) {
    cout << ans[i].first + 1 << ' ' << ans[i].second + 1 << '\n';
  }
  return 0;
}
