#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-11;
template <class T>
inline void ckmin(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
inline void ckmax(T &a, T b) {
  if (b > a) a = b;
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
const int maxsize = 1024;
int n, m;
int a[maxsize][maxsize];
int saved_a[maxsize][maxsize];
vector<vector<int>> ret;
int x[maxsize], y[maxsize];
bool c[maxsize][maxsize];
void show() {
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (m); ++j) {
      printf("%3d ", a[i][j]);
      if (j == m - 1) printf("\n");
    }
  printf("\n");
}
int ID(int x, int y) { return x * m + y; }
int get_dist(int id1, int id2) {
  return abs(id1 / m - id2 / m) + abs(id1 % m - id2 % m);
}
void apply(vector<int> p);
void solve(int x0, int y0) {
  int idx = ID(x0, y0);
  int src = -1;
  for (int x = 0; x < (n); ++x)
    for (int y = 0; y < (m); ++y)
      if (a[x][y] == idx) src = ID(x, y);
  assert(src >= 0);
  int current_dist = get_dist(idx, src);
  for (int dx = -1; dx <= 0; dx++)
    for (int dy = -1; dy <= 0; dy++)
      for (int b = 0; b < (2); ++b) {
        int x = src / m + dx;
        int y = src % m + dy;
        if (x < 0 || x >= n - 1 || y < 0 || y >= m - 1) continue;
        vector<int> p;
        p.push_back(ID(x, y));
        p.push_back(ID(x, y + 1));
        p.push_back(ID(x + 1, y + 1));
        p.push_back(ID(x + 1, y));
        if (b) reverse(p.begin(), p.end());
        bool ok = true;
        for (int x : p)
          if (c[x / m][x % m]) ok = false;
        if (!ok) continue;
        int next = -1;
        for (int i = 0; i < (((int)p.size())); ++i)
          if (p[i] == src) next = p[(i + 1) % ((int)p.size())];
        if (next < 0) continue;
        if (get_dist(idx, next) < current_dist) {
          for (int i = 0; i < (((int)p.size())); ++i)
            p[i] = a[p[i] / m][p[i] % m];
          apply(p);
          return;
        }
      }
  int sx = src / m, sy = src % m;
  if (sy == m - 1) {
    apply({a[sx][sy], a[sx + 1][sy], a[sx + 1][sy - 1], a[sx][sy - 1]});
    for (int i = 0; i < (2); ++i)
      apply({a[sx - 1][sy], a[sx][sy], a[sx + 1][sy], a[sx + 1][sy - 1],
             a[sx][sy - 1], a[sx - 1][sy - 1]});
    for (int i = 0; i < (2); ++i)
      apply({a[sx - 1][sy - 1], a[sx - 1][sy], a[sx][sy], a[sx][sy - 1]});
    return;
  }
  if (sx == n - 1) {
    apply({a[sx][sy], a[sx][sy + 1], a[sx - 1][sy + 1], a[sx - 1][sy]});
    for (int i = 0; i < (2); ++i)
      apply({a[sx][sy - 1], a[sx][sy], a[sx][sy + 1], a[sx - 1][sy + 1],
             a[sx - 1][sy], a[sx - 1][sy - 1]});
    for (int i = 0; i < (2); ++i)
      apply({a[sx - 1][sy - 1], a[sx - 1][sy], a[sx][sy], a[sx][sy - 1]});
    return;
  }
  printf("idx = %d   %d %d\n", idx, idx / m, idx % m);
  show();
  printf("dist = %d\n", current_dist);
  assert(0);
}
bool solve() {
  for (int x = 0; x < (n - 2); ++x)
    for (int y = 0; y < (m); ++y)
      if (!c[x][y]) {
        if (a[x][y] != ID(x, y)) solve(x, y);
        if (a[x][y] == ID(x, y)) c[x][y] = true;
        return true;
      }
  for (int y = 0; y < (m); ++y)
    for (int x = 0; x < (n); ++x)
      if (!c[x][y]) {
        if (x >= n - 2 && y >= m - 2 && (x == n - 1 || y == m - 1))
          return false;
        if (a[x][y] != ID(x, y)) solve(x, y);
        if (a[x][y] == ID(x, y)) c[x][y] = true;
        return true;
      }
  return false;
}
void apply(vector<int> p) {
  ret.push_back(p);
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (m); ++j) x[a[i][j]] = i, y[a[i][j]] = j;
  int c = ((int)p.size());
  for (int i = 0; i < (c); ++i)
    assert(abs(x[p[i]] - x[p[(i + 1) % c]]) +
               abs(y[p[i]] - y[p[(i + 1) % c]]) ==
           1);
  for (int i = 0; i < (c); ++i) a[x[p[(i + 1) % c]]][y[p[(i + 1) % c]]] = p[i];
}
int main() {
  std::ios::sync_with_stdio(false);
  while (cin >> n >> m) {
    for (int i = 0; i < (n); ++i)
      for (int j = 0; j < (m); ++j) {
        cin >> a[i][j];
        --a[i][j];
      }
    for (int i = 0; i < (n); ++i)
      for (int j = 0; j < (m); ++j) saved_a[i][j] = a[i][j];
    while (1) {
      for (int i = 0; i < (n); ++i)
        for (int j = 0; j < (m); ++j) a[i][j] = saved_a[i][j];
      for (int i = 0; i < (n); ++i)
        for (int j = 0; j < (m); ++j) c[i][j] = false;
      ret.clear();
      for (int i = 0; i < (1000); ++i) {
        int x = rand() % (n - 1);
        int y = rand() % (m - 1);
        vector<int> p;
        p.push_back(a[x][y]);
        p.push_back(a[x][y + 1]);
        p.push_back(a[x + 1][y + 1]);
        p.push_back(a[x + 1][y]);
        apply(p);
      }
      while (1) {
        if (!solve()) break;
      }
      bool ok = true;
      for (int i = 0; i < (n); ++i)
        for (int j = 0; j < (m); ++j)
          if (a[i][j] != ID(i, j)) ok = false;
      if (!ok) continue;
      printf("%d\n", ((int)ret.size()));
      for (vector<int> a : ret) {
        printf("%d", ((int)a.size()));
        for (int p : a) printf(" %d", p + 1);
        printf("\n");
      }
      break;
    }
    break;
  }
  return 0;
}
