#include <bits/stdc++.h>
using namespace std;
const int mn = 31;
int x[mn][mn];
int y[mn][mn];
int n, m;
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
int pre[901][mn][mn];
vector<pair<int, int> > q[901];
vector<pair<int, int> > qx[901];
int ipre() {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      q[y[i][j]].push_back(make_pair(i, j));
    }
  }
  for (int i = n - 1; i >= 0; i--) {
    for (int j = m - 1; j >= 0; j--) {
      qx[x[i][j]].push_back(make_pair(i, j));
    }
  }
  for (int k = 0; k < 901; k++) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        pre[k][i][j] = 1e9;
        for (int w = 0; w < q[k].size(); w++) {
          pre[k][i][j] = min(pre[k][i][j],
                             abs(i - q[k][w].first) + abs(j - q[k][w].second));
        }
      }
    }
  }
}
class c {
 public:
  int x[mn][mn];
  int px, py, ind, d, co;
  c() { px = py = 0; }
  c next(int i) {
    c res = *this;
    int nx, ny;
    nx = max(0, min(n - 1, px + dx[i]));
    ny = max(0, min(m - 1, py + dy[i]));
    swap(res.x[px][py], res.x[nx][ny]);
    res.px = nx;
    res.py = ny;
    return res;
  }
  int dist(c p) {
    int w = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        w += ((p.x[i][j] == x[i][j]) ? 1 : 0);
      }
    }
    return w;
  }
  int fy() const {
    int w = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        w += pre[x[i][j]][i][j];
      }
    }
    return w;
  }
  string tostr() const {
    stringstream ss;
    ss << px << " ";
    ss << py << " ";
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        ss << x[i][j] << " ";
      }
    }
    return ss.str();
  }
  bool operator<(const c &p) const { return tostr() < p.tostr(); }
  bool operator==(const c &p) const {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (x[i][j] != p.x[i][j]) return 0;
      }
    }
    return 1;
  }
  void p() const {
    printf("(%d %d) %d\n", px, py, fy());
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        printf("%.2d ", x[i][j]);
      }
      cout << endl;
    }
  }
};
class myc {
 public:
  bool operator()(const c &l, const c &r) const { return (l.co > r.co); }
};
bool c1() {
  map<int, int> ma1, ma2;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      ma1[x[i][j]]++;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      ma2[y[i][j]]++;
    }
  }
  return ma1 == ma2;
}
vector<c> ve;
map<c, int> la;
vector<pair<int, int> > res;
c cx, cy;
bool f(pair<int, int> ix) {
  priority_queue<c, vector<c>, myc> Q;
  if (ix.first != -1) {
    cx.px = ix.first;
    cx.py = ix.second;
    cx.ind = ve.size();
    cx.co = cx.fy();
    cx.d = 0;
    Q.push(cx);
    ve.push_back(cx);
    la[cx] = -1;
  } else {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cx.px = i;
        cx.py = j;
        cx.ind = ve.size();
        cx.co = cx.fy();
        cx.d = 0;
        Q.push(cx);
        ve.push_back(cx);
        la[cx] = -1;
      }
    }
  }
  c cu, cv;
  while (!Q.empty()) {
    cu = Q.top();
    Q.pop();
    if (cu == cy) {
      cy = cu;
      return 1;
    }
    for (int i = 0; i < 8; i++) {
      cv = cu.next(i);
      if (ix.first != -1) {
        cv.px = max(cv.px, n - 1 - 2);
      }
      if (la.count(cv) > 0) continue;
      cv.ind = ve.size();
      cv.d = cu.d + 1;
      cv.co = cv.fy();
      ve.push_back(cv);
      la[cv] = cu.ind;
      Q.push(cv);
    }
  }
  return 0;
}
bool vig[mn][mn];
bool vid[mn][mn];
vector<pair<int, int> > vd;
int dfs(pair<int, int> u, pair<int, int> fin) {
  vd.push_back(u);
  if (fin == u) return 1;
  pair<int, int> v;
  for (int i = 0; i < 8; i++) {
    v.first = max(0, min(n - 1, u.first + dx[i]));
    v.second = max(0, min(m - 1, u.second + dy[i]));
    if (vid[v.first][v.second] || vig[v.first][v.second]) continue;
    vid[v.first][v.second] = 1;
    if (dfs(v, fin)) return 1;
  }
  vd.pop_back();
  return 0;
}
pair<int, int> gx = make_pair(-1, -1);
pair<int, int> getx(int v) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (vig[i][j]) continue;
      if (make_pair(i, j) == gx) continue;
      if (x[i][j] == v) return make_pair(i, j);
    }
  }
  assert(false);
}
void g2(int i, int j) {
  vector<pair<int, int> > ve;
  memset(vid, 0, sizeof(vid));
  vd.clear();
  pair<int, int> ba = getx(y[i][j]);
  vid[ba.first][ba.second] = 1;
  dfs(ba, make_pair(i, j));
  ve = vd;
  for (int k = 1; k < ve.size(); k++) {
    memset(vid, 0, sizeof(vid));
    vd.clear();
    vid[ve[k - 1].first][ve[k - 1].second] = 1;
    vid[gx.first][gx.second] = 1;
    dfs(gx, ve[k]);
    vd.push_back(ve[k - 1]);
    for (int p = 1; p < vd.size(); p++) {
      swap(x[vd[p - 1].first][vd[p - 1].second], x[vd[p].first][vd[p].second]);
    }
    for (int p = 0; p < vd.size(); p++) {
      if (!res.empty() && res.back() == vd[p]) continue;
      res.push_back(vd[p]);
    }
    gx = ve[k - 1];
  }
  vig[i][j] = 1;
}
bool g() {
  gx = qx[y[n - 1][m - 1]][0];
  for (int i = 0; i < n - 2; i++) {
    for (int j = 0; j < m; j++) {
      g2(i, j);
    }
  }
  for (int j = 0; j < m - 2; j++) {
    for (int i = n - 2; i < n; i++) {
      g2(i, j);
    }
  }
}
int main() {
  scanf("%d", &(n));
  scanf("%d", &(m));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &(x[i][j]));
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &(y[i][j]));
    }
  }
  if (!c1()) {
    cout << -1 << endl;
    return 0;
  }
  ipre();
  if (n != 1 && m != 1) {
    g();
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cx.x[i][j] = x[i][j];
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cy.x[i][j] = y[i][j];
    }
  }
  if (!f(gx)) {
    cout << -1 << endl;
    return 0;
  }
  vector<pair<int, int> > rp;
  while (1) {
    rp.push_back(make_pair(cy.px, cy.py));
    if (la[cy] == -1) break;
    cy = ve[la[cy]];
  }
  reverse(rp.begin(), rp.end());
  for (int i = 0; i < rp.size(); i++) {
    if (!res.empty() && res.back() == rp[i]) continue;
    res.push_back(rp[i]);
  }
  cout << res.size() - 1 << endl;
  for (int i = 0; i < res.size(); i++) {
    printf("%d %d\n", res[i].first + 1, res[i].second + 1);
  }
  return 0;
}
