// 1000
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <queue>
#define N 220
using namespace std;
const int INF = 1e9;

int n, m, a[N][N], b[N][N], c[N][N], d[N];
int S, T, tot = 1, fir[N], nxt[N * N],  to[N * N], val[N * N];

inline void addE(int u, int v, int w) {
    nxt[++tot] = fir[u], fir[u] = tot, to[tot] = v, val[tot] = w;
    nxt[++tot] = fir[v], fir[v] = tot, to[tot] = u, val[tot] = 0;
}

int dep[N], cur[N];

inline bool bfs() {
    memset(dep, -1, sizeof dep);
    memcpy(cur, fir, sizeof fir);
    queue<int> q;
    while (!q.empty()) q.pop();
    dep[S] = 1, q.push(S);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = fir[u], v; i; i = nxt[i]) {
            v = to[i];
            if (dep[v] != -1 || !val[i]) continue;
            dep[v] = dep[u] + 1, q.push(v);
        }
    } return dep[T] != -1;
}

int dfs(int u, int now) {
    if (u == T || !now) return now;
    int res = 0;
    for (int &i = cur[u], v; i && now; i = nxt[i]) {
        v = to[i];
        if (dep[v] != dep[u] + 1 || !val[i]) continue;
        int tmp = dfs(v, min(now, val[i]));
        if (!tmp) continue;
        val[i] -= tmp, val[i ^ 1] += tmp;
        now -= tmp, res += tmp;
    } return res;
}

inline int dinic() {
    int res = 0, tmp;
    while (bfs()) {
        while ((tmp = dfs(S, INF)))
            res += tmp;
    } return res;
}

inline void erase(int u, int e) {
    if (fir[u] == e) return fir[u] = nxt[e], void();
    for (int i = fir[u]; i; i = nxt[i])
        if (nxt[i] == e) return nxt[i] = nxt[e], void();
    assert(0);
}

void write(int e[][N]) {
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            printf("%d%c", e[i][j], " \n"[j == m]);
}

queue<int> q[N][N];

int main() {
#ifdef whyqx
    freopen("work.in", "r", stdin);
    freopen("work.out", "w", stdout);
#endif

    cin >> n >> m, S = n + n + 1, T = n + n + 2;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) {
            scanf("%d", a[i] + j);
            int col = (a[i][j] - 1) / m + 1;
            addE(i, col + n, 1);
            q[i][col].push(a[i][j]);
        }

    for (int i = 1; i <= n; ++i)
        addE(S, i, 1), addE(i + n, T, 1);

    for (int k = 1; k <= m; ++k) {
        for (int i = fir[S]; i; i = nxt[i])
            val[i] = 1, val[i ^ 1] = 0;
        for (int i = fir[T]; i; i = nxt[i])
            val[i] = 0, val[i ^ 1] = 1;
        int tmp = dinic();
        assert(tmp == n);
        for (int u = 1; u <= n; ++u) {
            for (int i = fir[u]; i; i = nxt[i]) {
                if (val[i]) continue;
                b[u][k] = to[i] - n;
                erase(u, i), erase(to[i], i ^ 1);
                break;
            }
        }
    }

    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            c[i][j] = q[i][b[i][j]].front(), q[i][b[i][j]].pop();

    write(c);

    for (int j = 1; j <= m; ++j) {
        for (int i = 1; i <= n; ++i)
            d[i] = c[i][j];
        sort(d + 1, d + n + 1);
        for (int i = 1; i <= n; ++i)
            c[i][j] = d[i];
    }

    write(c);

    return 0;
}


Measured memory_bytes: 33536