#include <bits/stdc++.h>
const int N = 60;
int G[N][N], n, m, top;
std::vector<int> v[500000];
inline void out() {
  puts("");
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      printf("%d ", G[i][j]);
    }
    puts("");
  }
  puts("");
  return;
}
inline int id(int x, int y) { return (x - 1) * m + y; }
inline bool check() {
  return G[n - 1][m - 1] == id(n - 1, m - 1) && G[n - 1][m] == id(n - 1, m) &&
         G[n][m - 1] == id(n, m - 1) && G[n][m] == id(n, m);
}
inline void Cir(int x, int y, int f) {
  if (f == 0) {
    ++top;
    v[top].push_back(G[x][y]);
    v[top].push_back(G[x][y + 1]);
    v[top].push_back(G[x + 1][y + 1]);
    v[top].push_back(G[x + 1][y]);
    int t = G[x][y];
    G[x][y] = G[x + 1][y];
    G[x + 1][y] = G[x + 1][y + 1];
    G[x + 1][y + 1] = G[x][y + 1];
    G[x][y + 1] = t;
  } else {
    ++top;
    v[top].push_back(G[x][y]);
    v[top].push_back(G[x + 1][y]);
    v[top].push_back(G[x + 1][y + 1]);
    v[top].push_back(G[x][y + 1]);
    int t = G[x][y];
    G[x][y] = G[x][y + 1];
    G[x][y + 1] = G[x + 1][y + 1];
    G[x + 1][y + 1] = G[x + 1][y];
    G[x + 1][y] = t;
  }
  return;
}
inline void Move(int x, int y, int tx, int ty) {
  if (tx == n) {
    while (x != tx) {
      if (y == m) {
        Cir(x, y - 1, 0);
        x++;
      } else {
        Cir(x, y, 1);
        x++;
      }
    }
    while (y != ty) {
      Cir(x - 1, y - 1, 0);
      y--;
    }
  } else {
    if (x == n) {
      if (y == m) {
        Cir(x - 1, y - 1, 1);
        x--;
      } else {
        Cir(x - 1, y, 0);
        x--;
      }
    }
    while (y != ty) {
      if (y < ty) {
        Cir(x, y, 0);
        y++;
      } else {
        Cir(x, y - 1, 1);
        y--;
      }
    }
    while (x != tx) {
      Cir(x - 1, y, 0);
      x--;
    }
  }
  return;
}
inline void getPos(int &i, int &j, int t) {
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= m; j++) {
      if (G[i][j] == t) {
        return;
      }
    }
  }
  return;
}
inline void SwapDown() {
  Cir(n - 1, m - 1, 0);
  Cir(n - 1, m - 2, 0);
  ++top;
  v[top].push_back(G[n - 1][m - 2]);
  v[top].push_back(G[n][m - 2]);
  v[top].push_back(G[n][m - 1]);
  v[top].push_back(G[n][m]);
  v[top].push_back(G[n - 1][m]);
  v[top].push_back(G[n - 1][m - 1]);
  int t = G[n - 1][m - 2];
  G[n - 1][m - 2] = G[n - 1][m - 1];
  G[n - 1][m - 1] = G[n - 1][m];
  G[n - 1][m] = G[n][m];
  G[n][m] = G[n][m - 1];
  G[n][m - 1] = G[n][m - 2];
  G[n][m - 2] = t;
  return;
}
inline void SwapUp() {
  Cir(n - 1, m - 1, 1);
  Cir(n - 1, m - 2, 1);
  ++top;
  v[top].push_back(G[n - 1][m - 2]);
  v[top].push_back(G[n - 1][m - 1]);
  v[top].push_back(G[n - 1][m]);
  v[top].push_back(G[n][m]);
  v[top].push_back(G[n][m - 1]);
  v[top].push_back(G[n][m - 2]);
  int t = G[n - 1][m - 2];
  G[n - 1][m - 2] = G[n][m - 2];
  G[n][m - 2] = G[n][m - 1];
  G[n][m - 1] = G[n][m];
  G[n][m] = G[n - 1][m];
  G[n - 1][m] = G[n - 1][m - 1];
  G[n - 1][m - 1] = t;
  return;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &G[i][j]);
    }
  }
  int x, y;
  for (int i = 1; i <= n - 2; i++) {
    for (int j = 1; j <= m - 2; j++) {
      getPos(x, y, id(i, j));
      Move(x, y, i, j);
    }
    getPos(x, y, i * m);
    Move(x, y, i, m - 1);
    getPos(x, y, i * m - 1);
    if (x == i && y == m) {
      Cir(x, y - 1, 0);
      Cir(x + 1, y - 1, 0);
      Cir(x, y - 1, 1);
      getPos(x, y, i * m - 1);
    }
    Move(x, y, i + 1, m - 1);
    Cir(i, m - 1, 0);
  }
  for (int i = 1; i <= m - 2; i++) {
    getPos(x, y, id(n - 1, i));
    Move(x, y, n, i);
    getPos(x, y, id(n, i));
    if (x == n - 1 && y == i) {
      Cir(x, y, 0);
      Cir(x, y + 1, 0);
      Cir(x, y, 1);
    }
    getPos(x, y, id(n, i));
    Move(x, y, n, i + 1);
    Cir(n - 1, i, 0);
  }
  int xx, yy;
  getPos(x, y, id(n - 1, m - 1));
  getPos(xx, yy, id(n - 1, m));
  if (abs(x - xx) + abs(y - yy) != 1) {
    SwapDown();
  }
  if (x == n && xx == n) {
    Cir(n - 1, m - 1, 0);
    Cir(n - 1, m - 1, 0);
  }
  getPos(x, y, id(n - 1, m - 1));
  getPos(xx, yy, id(n - 1, m));
  if (x != xx) {
    Cir(n - 1, m - 1, y == m);
  }
  if (G[n][m - 1] > G[n][m]) {
    SwapDown();
  }
  if (G[n - 1][m - 1] > G[n - 1][m]) {
    SwapUp();
  }
  printf("%d\n", top);
  for (int i = 1; i <= top; i++) {
    int len = v[i].size();
    printf("%d ", len);
    for (int j = 0; j < len; j++) {
      printf("%d ", v[i][j]);
    }
    puts("");
  }
  return 0;
}
