#include <bits/stdc++.h>
using namespace std;
const int N = 22;
int n, m;
int a[N][N];
vector<vector<int>> ans;
void showState() {
  cerr << "ShowStart!" << endl;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) cerr << a[i][j] << ' ';
    cerr << endl;
  }
  cerr << "ShowEnd!" << endl;
}
void rotate(int x, int y, int dir) {
  vector<int> vec;
  vector<pair<int, int>> pos;
  vec.emplace_back(a[x][y]), pos.emplace_back(x, y);
  vec.emplace_back(a[x][y + 1]), pos.emplace_back(x, y + 1);
  vec.emplace_back(a[x + 1][y + 1]), pos.emplace_back(x + 1, y + 1);
  vec.emplace_back(a[x + 1][y]), pos.emplace_back(x + 1, y);
  if (dir) reverse(vec.begin(), vec.end()), reverse(pos.begin(), pos.end());
  for (int i = 0; i < vec.size(); i++) {
    int _x = pos[i].first, _y = pos[i].second;
    a[_x][_y] = vec[(i - 1 + pos.size()) % pos.size()];
  }
  ans.push_back(vec);
}
void getPosition(int x, int &px, int &py) {
  for (int _x = 0; _x < n; _x++) {
    for (int _y = 0; _y < m; _y++) {
      if (a[_x][_y] == x) {
        px = _x, py = _y;
        return;
      }
    }
  }
}
struct state {
  int p[9];
  int hash() {
    int pw = 1, val = 0;
    for (int i = 0; i < 9; i++) {
      val += p[i] * pw;
      pw *= 9;
    }
    return val;
  }
};
unordered_map<int, int> vis;
unordered_map<int, pair<int, vector<int>>> up;
vector<vector<int>> arrays;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a[i][j];
    }
  }
  for (int i = 0; i < n - 3; i++) {
    for (int j = 0; j < m - 1; j++) {
      int x = i * m + j + 1, px, py;
      getPosition(x, px, py);
      while (py > j) {
        if (px == n - 1)
          rotate(px - 1, py - 1, 0), py--;
        else
          rotate(px, py - 1, 1), py--;
      }
      while (py < j) {
        if (px == n - 1)
          rotate(px - 1, py, 1), py++;
        else
          rotate(px, py, 0), py++;
      }
      while (px > i) {
        rotate(px - 1, py, 0), px--;
      }
    }
    int j = m - 1;
    int x = i * m + j + 1, px, py;
    getPosition(x, px, py);
    if (px == i && py == j) continue;
    while (py < j) {
      if (px == n - 1)
        rotate(px - 1, py, 1), py++;
      else
        rotate(px, py, 0), py++;
    }
    while (px > i + 2) rotate(px - 1, py - 1, 1), px--;
    while (px < i + 2) rotate(px, py - 1, 0), px++;
    rotate(i, j - 1, 0);
    rotate(i + 1, j - 1, 1);
    rotate(i, j - 1, 1);
  }
  for (int j = 0; j < m - 3; j++) {
    for (int i = n - 3; i < n - 1; i++) {
      int x = i * m + j + 1, px, py;
      getPosition(x, px, py);
      while (px > i) {
        if (py == m - 1)
          rotate(px - 1, py - 1, 1), px--;
        else
          rotate(px - 1, py, 0), px--;
      }
      while (px < i) {
        if (py == m - 1)
          rotate(px, py - 1, 0), px++;
        else
          rotate(px, py, 1), px++;
      }
      while (py > j) {
        rotate(px, py - 1, 1), py--;
      }
    }
    int i = n - 1;
    int x = i * m + j + 1, px, py;
    getPosition(x, px, py);
    if (px == i && py == j) continue;
    while (px < i) {
      if (py == m - 1)
        rotate(px, py - 1, 0), px++;
      else
        rotate(px, py, 1), px++;
    }
    while (py > j + 2) rotate(px - 1, py - 1, 0), py--;
    while (py < j + 2) rotate(px - 1, py, 1), py++;
    rotate(i - 1, j, 1);
    rotate(i - 1, j + 1, 0);
    rotate(i - 1, j, 0);
  }
  vector<int> rest;
  for (int i = n - 3; i < n; i++) {
    for (int j = m - 3; j < m; j++) {
      rest.push_back(a[i][j]);
    }
  }
  sort(rest.begin(), rest.end());
  int b[3][3];
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      b[i][j] = lower_bound(rest.begin(), rest.end(), a[i + n - 3][j + m - 3]) -
                rest.begin();
    }
  }
  arrays.push_back({0, 1, 4, 3});
  arrays.push_back({1, 2, 5, 4});
  arrays.push_back({3, 4, 7, 6});
  arrays.push_back({4, 5, 8, 7});
  arrays.push_back({0, 1, 2, 5, 4, 3});
  arrays.push_back({1, 2, 5, 8, 7, 4});
  arrays.push_back({3, 4, 5, 8, 7, 6});
  arrays.push_back({0, 1, 4, 7, 6, 3});
  arrays.push_back({1, 2, 5, 8, 7, 6, 3, 4});
  arrays.push_back({0, 1, 4, 5, 8, 7, 6, 3});
  arrays.push_back({0, 1, 2, 5, 8, 7, 4, 3});
  arrays.push_back({0, 1, 2, 5, 4, 7, 6, 3});
  arrays.push_back({0, 1, 2, 5, 8, 7, 6, 3});
  for (int i = 0; i < 13; i++) {
    auto t = arrays[i];
    reverse(t.begin(), t.end());
    arrays.push_back(t);
  }
  state st, final;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) st.p[i * 3 + j] = b[i][j];
  }
  for (int i = 0; i < 9; i++) final.p[i] = i;
  int finalstate = final.hash();
  int start = st.hash();
  queue<state> que;
  vis[start] = 1;
  que.push(st);
  if (start != finalstate)
    while (!que.empty()) {
      state cur = que.front();
      int curstate = cur.hash();
      que.pop();
      int flg = 0;
      for (auto t : arrays) {
        state nw = cur;
        for (int i = t.size() - 2; i >= 0; i--) {
          swap(nw.p[t[i]], nw.p[t[(i + 1) % t.size()]]);
        }
        int nwstate = nw.hash();
        if (vis[nwstate]) continue;
        if (nwstate == finalstate) {
          flg = 1;
          vector<vector<int>> append;
          append.push_back(t);
          while (curstate != start) {
            auto tt = up[curstate];
            append.push_back(tt.second);
            curstate = tt.first;
          }
          reverse(append.begin(), append.end());
          for (auto t : append) {
            vector<int> nvec;
            for (int x : t) nvec.push_back(rest[st.p[x]]);
            for (int i = t.size() - 2; i >= 0; i--) {
              swap(st.p[t[i]], st.p[t[(i + 1) % t.size()]]);
            }
            ans.push_back(nvec);
          }
          break;
        }
        que.push(nw);
        vis[nwstate] = 1;
        up[nwstate] = make_pair(curstate, t);
      }
      if (flg) break;
    }
  cout << ans.size() << endl;
  for (auto t : ans) {
    cout << t.size();
    for (int x : t) cout << ' ' << x;
    cout << endl;
  }
}
