#include <bits/stdc++.h>
#define FOR(i, a, n) for(ll i = (ll)a; i < (ll)n; i++)
#define rep(i, n) FOR(i, 0, n)
#define ALL(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;

constexpr ll Mod = 998244353;
constexpr ll mod = 1e9 + 7;
constexpr ll inf = 1LL << 60;

template <typename T> constexpr bool chmax(T &a, const T b) {
    if(a >= b) return false;
    a = b;
    return true;
}
template <typename T> constexpr bool chmin(T &a, const T b) {
    if(a <= b) return false;
    a = b;
    return true;
}

/*-------------------------------------------*/

using FLOW = int;
const int MAX_V = 222;
const FLOW INF = 100000000;

// 辺
struct Edge {
    int rev, from, to, x;
    FLOW cap, icap;
    Edge(int r, int f, int t, FLOW c, int x = 0)
        : rev(r), from(f), to(t), cap(c), icap(c), x(x) {}
};

// グラフ
struct Graph {
    int V;
    vector<Edge> list[MAX_V];
    Graph(int n = 0) : V(n) { rep(i, MAX_V) list[i].clear(); }
    void init(int n = 0) {
        V = n;
        rep(i, MAX_V) list[i].clear();
    }
    void resize(int n = 0) { V = n; }
    void reset() {
        rep(i, V) rep(j, list[i].size()) list[i][j].cap = list[i][j].icap;
    }
    inline vector<Edge> &operator[](int i) { return list[i]; }
    Edge &redge(Edge e) {
        if(e.from != e.to) return list[e.to][e.rev];
        return list[e.to][e.rev + 1];
    }
    void addedge(int from, int to, FLOW cap, int x = 0) {
        list[from].push_back(Edge((int)list[to].size(), from, to, cap, x));
        list[to].push_back(Edge((int)list[from].size() - 1, to, from, 0, x));
    }
};

static int level[MAX_V];
static int iter[MAX_V];

void dibfs(Graph &G, int s) {
    rep(i, MAX_V) level[i] = -1;
    level[s] = 0;
    queue<int> que;
    que.push(s);
    while(!que.empty()) {
        int v = que.front();
        que.pop();
        for(Edge e : G[v]) {
            if(level[e.to] < 0 && e.cap > 0) {
                level[e.to] = level[v] + 1;
                que.push(e.to);
            }
        }
    }
}

FLOW didfs(Graph &G, int v, int t, FLOW f) {
    if(v == t) return f;
    for(int &i = iter[v]; i < G[v].size(); i++) {
        Edge &e = G[v][i], &re = G.redge(e);
        if(level[v] < level[e.to] && e.cap > 0) {
            FLOW d = didfs(G, e.to, t, min(f, e.cap));
            if(d > 0) {
                e.cap -= d;
                re.cap += d;
                return d;
            }
        }
    }
    return 0;
}

// 最大流
FLOW Dinic(Graph &G, int s, int t) {
    FLOW res = 0;
    while(true) {
        dibfs(G, s);
        if(level[t] < 0) return res;
        memset(iter, 0, sizeof(iter));
        FLOW flow;
        while(flow = didfs(G, s, t, INF) > 0)
            res += flow;
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    int n, m;
    cin >> n >> m;

    Graph G(2 * n + 2);
    int S = 2 * n;
    int T = 2 * n + 1;

    vector<vector<int>> B(m, vector<int>(n));

    rep(i, n) {
        rep(j, m) {
            int x;
            cin >> x;
            G.addedge(i, n + (x - 1) / m, 1, x);
        }
        G.addedge(S, i, 1);
        G.addedge(n + i, T, 1);
    }

    rep(i, m) {
        Dinic(G, S, T);
        for(auto &e : G[S])
            e.cap = e.icap;
        rep(j, n) {
            for(auto &e : G[j + n])
                e.cap = e.icap;
            for(auto &e : G[j]) {
                if(e.icap == 1 && e.cap == 0) {
                    e.icap = 0;
                    B[i][j] = e.x;
                }
            }
        }
    }
    rep(i, n) {
        rep(j, m) cout << B[j][i] << " ";
        cout << endl;
    }
    rep(j, m) sort(ALL(B[j]));
    rep(i, n) {
        rep(j, m) cout << B[j][i] << " ";
        cout << endl;
    }

    return 0;
}

Measured memory_bytes: 1024