/*
ЗАПУСКАЕМ
░ГУСЯ░▄▀▀▀▄░РАБОТЯГУ░░
▄███▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▌░░░░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
 */
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>
 
using namespace std;
template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { x = (x > y ? y: x);}
template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { x = (x < y ? y: x);}
#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define left left224
#define right right224
#define next next224
#define rank rank224
#define prev prev224
#define y1 y1224
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define files(FILENAME) read(FILENAME), write(FILENAME)
#define pb push_back
#define mp make_pair
using ll = long long;
const string FILENAME = "input";
const int MAXN = 101;


#define INF 1000000002


struct edge {
    int a, b, cap, flow;
};


int s, t, d[2601], ptr[2601], q[2601];
vector<edge> e;
vector<int> g[2601];

 
void add_edge(int a, int b, int cap) {
    edge e1 = {a, b, cap, 0};
    edge e2 = {b, a, 0, 0};
    g[a].push_back((int)e.size());
    e.push_back(e1);
    g[b].push_back((int)e.size());
    e.push_back(e2);
}


bool bfs() {
    int qh = 0, qt = 0;
    q[qt++] = s;
    memset(d, -1, sizeof(d));
    d[s] = 0;
    while (qh < qt && d[t] == -1) {
        int v = q[qh++];
        for (unsigned int i = 0; i < g[v].size(); i++) {
            int id = g[v][i], to = e[id].b;
            if (d[v] != -1 && d[to] == -1 && e[id].flow < e[id].cap) {
                q[qt++] = to;
                d[to] = d[v] + 1;
            }
        }
    }
    return d[t] != -1;
}
 
int dfs(int v, int flow) {
    if (!flow) { 
        return 0;
    }
    if (v == t) { 
        return flow;
    }
    for (; ptr[v] < (int)g[v].size(); ptr[v]++) {
        int id = g[v][ptr[v]], to = e[id].b;
        if (d[to] != d[v] + 1)  {
            continue;
        }
        int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
        if (pushed) {
            e[id].flow += pushed;
            e[id ^ 1].flow -= pushed;
            return pushed;
        }
    }
    return 0;
}
 

int dinic() {
    int flow = 0;
    for (;;) {
        if (!bfs()) {
            break;
        }
        memset(ptr, 0, sizeof(ptr));
        while (int pushed = dfs(s, INF)) {
            flow += pushed;
        }
    }
    return flow;
}


int n, m;


vector<pair<int, int> > findmatching() {
    s = 0;
    t = 2 * n + 1;
    int tt = dinic();
    assert(tt == n);
    vector<pair<int, int> > res;
    for (auto x: e) {
        if (x.flow == 1 && x.a >= 1 && x.a <= n && x.b >= n + 1 && x.b <= 2 * n) {
            res.pb({x.a - 1, x.b - n - 1});
        }
    }
    e.clear();
    for (int i = 0; i <= 2 * n + 2; i++) {
        g[i].clear();
    }
    return res;
}


int a[MAXN][MAXN];
int b[MAXN][MAXN];



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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //read(FILENAME); 
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    for (int j = 0; j < m; j++) {
        for (int i = 0; i < n; i++) {
            add_edge(0, i + 1, 1);
            add_edge(i + n + 1, 2 * n + 1, 1);
        }
        for (int i = 0; i < n; i++) {
            for (int t = j; t < m; t++) {
                add_edge(i + 1, n + 1 + color(a[i][t]), 1);
            }
        }
        auto x = findmatching();
        for (auto z: x) {
            for (int t = j; t < m; t++) {
                if (color(a[z.first][t]) == z.second) {
                    swap(a[z.first][t], a[z.first][j]);
                    break;
                }
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << a[i][j] << ' ';
        }
        cout << '\n';
    }
    for (int i = 0; i < m; i++) {
        vector<int> st;
        for (int j = 0; j < n; j++) {
            st.pb(a[j][i]);
        }
        sort(all(st));
        for (int j = 0; j < n; j++) {
            a[j][i] = st[j];
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << a[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0; 
}



Measured memory_bytes: 1020