#include <bits/stdc++.h>
using namespace std;
const int maxn = 105 * 105 + 2 * 105;
const int inf = 1e9;
struct Flow {
  int s, t, head[maxn], cur[maxn], cnt, q[maxn], rk[maxn];
  struct gg {
    int u, v, w, next;
  } side[maxn * 2];
  Flow() { s = maxn - 3, t = maxn - 2, cnt = 1; }
  void reset() {
    cnt = 1;
    memset(head, 0, sizeof(head));
  }
  void ins(int u, int v) {
    side[++cnt] = (gg){u, v, 1, head[u]};
    head[u] = cnt;
    side[++cnt] = (gg){v, u, 0, head[v]};
    head[v] = cnt;
  }
  bool bfs() {
    memset(rk, 0, sizeof(rk));
    int hd = 1, tl = 1;
    q[tl] = s;
    rk[s] = 1;
    while (hd <= tl) {
      int u = q[hd++];
      for (int i = head[u]; i; i = side[i].next) {
        int v = side[i].v;
        if (rk[v] || !side[i].w) continue;
        rk[v] = rk[u] + 1;
        q[++tl] = v;
      }
    }
    return rk[t];
  }
  int dfs(int u, int flow) {
    if (u == t) return flow;
    int tot = 0;
    for (int &i = cur[u]; i; i = side[i].next) {
      int v = side[i].v;
      if (rk[u] + 1 != rk[v] || !side[i].w) continue;
      int sent = dfs(v, min(flow, side[i].w));
      flow -= sent;
      tot += sent;
      side[i].w -= sent;
      side[i ^ 1].w += sent;
    }
    return tot;
  }
  void dinic() {
    int maxflow = 0;
    while (bfs()) {
      memcpy(cur, head, sizeof(head));
      maxflow += dfs(s, inf);
    }
  }
} f;
int A[105][105], B[105][105], C[105][105], col[105][105];
bool used[105][105];
int n, m;
int get_col(int num) {
  int tmp = num % m;
  if (!tmp) tmp = m;
  return (num - tmp) / m + 1;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = (1), iend = (n); i <= iend; i++)
    for (int j = (1), jend = (m); j <= jend; j++)
      scanf("%d", &A[i][j]), col[i][j] = get_col(A[i][j]);
  for (int floor = (1), floorend = (m); floor <= floorend; floor++) {
    f.reset();
    for (int i = (1), iend = (n); i <= iend; i++)
      f.ins(f.s, i), f.ins(i + n, f.t);
    for (int i = (1), iend = (n); i <= iend; i++)
      for (int j = (1), jend = (m); j <= jend; j++)
        if (!used[i][j]) f.ins(col[i][j], i + n);
    f.dinic();
    for (int i = (n + 1), iend = (2 * n); i <= iend; i++) {
      for (int j = f.head[i]; j; j = f.side[j].next) {
        int v = f.side[j].v;
        if (v <= n && f.side[j].w) {
          for (int k = (1), kend = (m); k <= kend; k++) {
            if (col[i - n][k] == v && !used[i - n][k]) {
              used[i - n][k] = 1;
              B[i - n][floor] = A[i - n][k];
              break;
            }
          }
          break;
        }
      }
    }
  }
  for (int i = (1), iend = (n); i <= iend; i++)
    for (int j = (1), jend = (m); j <= jend; j++)
      C[get_col(B[i][j])][j] = B[i][j];
  for (int i = (1), iend = (n); i <= iend; i++) {
    for (int j = (1), jend = (m); j <= jend; j++) printf("%d ", B[i][j]);
    printf("\n");
  }
  for (int i = (1), iend = (n); i <= iend; i++) {
    for (int j = (1), jend = (m); j <= jend; j++) printf("%d ", C[i][j]);
    printf("\n");
  }
  return 0;
}
