//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
#define mem(a,v) memset((a), (v), sizeof (a))
#define enl printf("\n")
#define case(t) printf("Case #%d: ", (t))
#define ni(n) scanf("%d", &(n))
#define nl(n) scanf("%lld", &(n))
#define nai(a, n) for (int i = 0; i < (n); i++) ni(a[i])
#define nal(a, n) for (int i = 0; i < (n); i++) nl(a[i])
#define pri(n) printf("%d\n", (n))
#define prl(n) printf("%lld\n", (n))
#define pii pair<int, int>
#define pil pair<int, long long>
#define pll pair<long long, long long>
#define vii vector<pii>
#define vil vector<pil>
#define vll vector<pll>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef cc_hash_table<int,int,hash<int>> ht;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> oset;
const double pi = acos(-1);
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;
const int MAXN = 2e2 + 5;
const double eps = 1e-9;
int a[MAXN][MAXN];
int b[MAXN][MAXN];

struct BPM {
    vi adj[MAXN];
    int l, r, dist[MAXN], match[MAXN];

    void init(int l1, int r1) {
        l = l1, r = r1;
    }

    void addEdge(int u, int v) {
        adj[u].pb(v + l);
        adj[v + l].pb(u);
    }

    void reset() {
        for (int i = 0; i <= l + r; i++)
            adj[i].clear();
        l = 0, r = 0;
    }

    bool dfs(int u) {
        if (u == 0) return 1;
        for (int v: adj[u]) {
            if (dist[match[v]] == dist[u] + 1 && dfs(match[v])) {
                match[v] = u;
                match[u] = v;
                return 1;
            }
        }
        dist[u] = INF;
        return 0;
    }

    bool bfs() {
        deque<int> pq;
        for (int i = 1; i <= l; i++) {
            if (match[i] == 0) {
                dist[i] = 0;
                pq.pb(i);
            } else
                dist[i] = INF;
        }
        dist[0] = INF;
        while (!pq.empty()) {
            int u = pq.front(); pq.pop_front();
            if (u == 0) continue;
            for (int v: adj[u]) {
                if (dist[match[v]] == INF) {
                    dist[match[v]] = dist[u] + 1;
                    pq.pb(match[v]);
                }
            }
        }
        if (dist[0] == INF)
            return 0;
        return 1;
    }

    // runtime: O(sqrt(V)E)
	// l nodes left, r nodes right
    int matching() {
        int ret = 0;
        memset(match, 0, sizeof match);
        while (bfs())
            for (int i = 1; i <= l; i++)
                if (match[i] == 0 && dfs(i))
                    ret++;
        return ret;
    }
} g;

int main() {
	int n, m;
	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++) {
		g.reset();
		g.init(n, n);
		for (int j = i; j <= m; j++)
			for (int k = 1; k <= n; k++)
				g.addEdge(k, (a[k][j]-1) / m + 1);
		g.matching();
		for (int j = 1; j <= n; j++) {
			for (int k = i; k <= m; k++) {
				if (g.match[j] != (a[j][k]-1) / m + 1 + n)
					continue;
				swap(a[j][k], a[j][i]);
				break;
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			printf("%d ", a[i][j]);
		enl;
	}
	//enl;
	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= n; j++)
			b[(a[j][i]-1)/m+1][i] = a[j][i];
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			printf("%d ", b[i][j]);
		enl;
	}
	return 0;
}


Measured memory_bytes: 640