#include <bits/stdc++.h>

using namespace std;

namespace max_flow {

const int max_v = 3 * 105, inf = 1000111222;

struct edge {
    int to, residual_capacity;

    edge(int to, int residual_capacity): to(to), residual_capacity(residual_capacity) {
    }
};

vector<edge> edges;
vector<int> g[max_v];

void clr() {
    edges.clear();
    for (int i = 0; i < max_v; ++i) {
        g[i].clear();
    }
}

void add_edge(int u, int v, int capacity) {
    g[u].push_back(edges.size());
    edges.push_back({v, capacity});
    g[v].push_back(edges.size());
    edges.push_back({u, 0});
}

int h[max_v], num[max_v];

bool bfs(int s, int t) {
    for (int i = 0; i <= t; ++i) {
        h[i] = -1;
    }
    h[s] = 0;
    queue<int> q;
    q.push(s);
    while (!q.empty()) {
        int v = q.front();
        q.pop();
        for (int id : g[v]) {
            if (edges[id].residual_capacity && h[edges[id].to] == -1) {
                h[edges[id].to] = h[v] + 1;
                q.push(edges[id].to);
            }
        }
    }
    return h[t] != -1;
}

int dfs(int v, int t, int f) {
    if (v == t) {
        return f;
    }
    for (int &i = num[v]; i < g[v].size(); ++i) {
        const int id = g[v][i];
        if (edges[id].residual_capacity && h[v] + 1 == h[edges[id].to]) {
            int res = dfs(edges[id].to, t, min(f, edges[id].residual_capacity));
            if (res) {
                edges[id].residual_capacity -= res;
                edges[id ^ 1].residual_capacity += res;
                return res;
            }
        }
    }
    return 0;
}

int dinic(int s, int t) {
    int res = 0;
    while (bfs(s, t)) {
        memset(num, 0, sizeof(num));
        while (int f = dfs(s, t, inf)) {
            res += f;
        }
    }
    return res;
}

}

const int max_n = 111, inf = 1000111222;

int n, m, a[max_n][max_n], num[max_n][max_n];
vector<int> all[max_n][max_n];
int b[max_n][max_n];

int get_num(int x) {
    return (x - 1) / m;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> a[i][j];
            num[i][j] = get_num(a[i][j]);
            //cout << num[i][j] << " ";
            all[i][num[i][j]].push_back(j);
        }
        //cout << endl;
    }
    for (int i = 0; i < m; ++i) {
        int s = 2 * n;
        int t = s + 1;
        max_flow::clr();
        for (int j = 0; j < n; ++j) {
            max_flow::add_edge(s, j, 1);
            max_flow::add_edge(n + j, t, 1);
            for (int k = 0; k < n; ++k) {
                if (all[j][k].size()) {
                    max_flow::add_edge(j, n + k, 1);
                }
            }
        }
        int f = max_flow::dinic(s, t);
        assert(f == n);
        for (int j = 0; j < n; ++j) {
            for (int id : max_flow::g[j]) {
                int to = max_flow::edges[id].to;
                if (n <= to && to < 2 * n && max_flow::edges[id].residual_capacity == 0) {
                    to -= n;
                    //cout << "$" << j << " " << to << " " << all[j][to].size() << endl;
                    b[j][i] = a[j][all[j][to].back()];
                    all[j][to].pop_back();
                }
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << b[i][j] << " ";
        }
        cout << "\n";
    }
    for (int i = 0; i < m; ++i) {
        vector<int> v;
        for (int j = 0; j < n; ++j) {
            v.push_back(b[j][i]);
        }
        sort(v.begin(), v.end());
        for (int j = 0; j < n; ++j) {
            b[j][i] = v[j];
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << b[i][j] << " ";
        }
        cout << "\n";
    }
    return 0;
}


Measured memory_bytes: 1504