#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 233;

int N, M, A[MAX_N][MAX_N];

int belong_row(int x) { return (x + M - 1) / M; }

namespace Dinic {
    struct Edge;

    struct Node {
        Edge *head, *curr;
        int dis, info;
        Node(int info = 0);
    };
    vector<Node *> nodes;
    Node::Node(int info) : head(nullptr), info(info) { nodes.push_back(this); }

    struct Edge {
        Node *to;
        Edge *nxt, *rev;
        int cap;
        Edge(Node *from, Node *to, int cap) : to(to), nxt(from->head), cap(cap) {
            from->head = this;
        }
    };

    void add_edge(Node *from, Node *to, int cap) {
        new Edge(from, to, cap);
        new Edge(to, from, 0);
        (from->head->rev = to->head)->rev = from->head;
    }

    bool bfs(Node *S, Node *T) {
        for (Node *i : nodes) i->dis = 0, i->curr = i->head;
        queue<Node *> q; S->dis = 1; q.push(S);
        while (!q.empty()) {
            Node *x = q.front(); q.pop();
            for (Edge *i = x->head; i; i = i->nxt) {
                if (!i->cap) continue;
                Node *y = i->to;
                if (!y->dis) {
                    y->dis = x->dis + 1;
                    if (y == T) return true;
                    q.push(y);
                }
            }
        }
        return false;
    }

    int dfs(Node *x, Node *T, int limit = INT_MAX) {
        if (x == T) return limit;
        for (Edge *&i = x->curr; i; i = i->nxt) {
            if (!i->cap || i->to->dis != x->dis + 1) continue;
            int t = dfs(i->to, T, min(limit, i->cap));
            if (t) {
                i->cap -= t;
                i->rev->cap += t;
                return t;
            }
        }
        return 0;
    }

    int main(Node *S, Node *T) {
        int flow = 0;
        while (bfs(S, T)) {
            int t;
            while (t = dfs(S, T)) {
                flow += t;
            }
        }
        return flow;
    }

    void clear() {
        for (Node *i : nodes) {
            for (Edge *j = i->head, *k; j; j = k) {
                k = j->nxt;
                delete j;
            }
            delete i;
        }
        nodes.clear();
    }
}

int main() {
    scanf("%d%d", &N, &M);
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            scanf("%d", &A[i][j]);
        }
    }
    for (int i = 1; i <= M; i++) {
        Dinic::Node *S = new Dinic::Node(), *T = new Dinic::Node(), *L[MAX_N], *R[MAX_N];
        for (int j = 1; j <= N; j++) {
            L[j] = new Dinic::Node();
            R[j] = new Dinic::Node(j);
        }
        for (int j = 1; j <= N; j++) {
            Dinic::add_edge(S, L[j], 1);
            Dinic::add_edge(R[j], T, 1);
        }
        for (int j = 1; j <= N; j++) {
            for (int k = i; k <= M; k++) {
                Dinic::add_edge(L[j], R[belong_row(A[j][k])], 1);
            }
        }
        int flow = Dinic::main(S, T);
        assert(flow == N);
        int match[MAX_N];
        for (int j = 1; j <= N; j++) {
            for (Dinic::Edge *k = L[j]->head; k; k = k->nxt) {
                if (k->to->info && !k->cap)
                    match[j] = k->to->info;
            }
        }
        for (int j = 1; j <= N; j++) {
            for (int k = i; k <= M; k++) {
                if (belong_row(A[j][k]) == match[j]) {
                    swap(A[j][i], A[j][k]);
                    break;
                }
            }
        }
        Dinic::clear();
    }
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }
    for (int i = 1; i <= M; i++) {
        int t[MAX_N];
        for (int j = 1; j <= N; j++)
            t[j] = A[j][i];
        sort(t + 1, t + N + 1);
        for (int j = 1; j <= N; j++)
            A[j][i] = t[j];
    }
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }
}


Measured memory_bytes: 1408