#include <bits/stdc++.h>
using namespace std;
void open() {
  freopen("game.in", "r", stdin);
  freopen("game.out", "w", stdout);
}
int dx[8] = {-1, 0, 1, -1, 0, 1, -1, 1};
int dy[8] = {-1, -1, -1, 1, 1, 1, 0, 0};
class chess {
 public:
  int ori[33][33], end[33][33], mid[33][33], m, n, a, b, num[2][901];
  bool use[33][33];
  pair<int, int> pre[33][33];
  vector<pair<int, int> > ans;
  void work() {
    read();
    all_judge();
    pre_judge();
    if (min(n, m) == 1) work1();
    top_judge();
  }

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