#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define MOD @
#define ADD(X,Y) ((X) = ((X) + (Y)%MOD) % MOD)
typedef long long i64; typedef vector<int> ivec; typedef vector<string> svec;

namespace MF {
	#define MAXN 1000
	#define MAXM 101010
	#define wint int
	const wint wEPS = 0;
	const wint wINF = 1001001001;
	int n, m, ptr[MAXN], next[MAXM], zu[MAXM];
	wint capa[MAXM], tof;
	int lev[MAXN], see[MAXN], que[MAXN], *qb, *qe;
	void init(int _n) {
		n = _n; m = 0; memset(ptr, ~0, n * 4);
	}
	void ae(int u, int v, wint w0, wint w1 = 0) {
		next[m] = ptr[u]; ptr[u] = m; zu[m] = v; capa[m] = w0; ++m;
		next[m] = ptr[v]; ptr[v] = m; zu[m] = u; capa[m] = w1; ++m;
	}
	wint augment(int src, int ink, wint flo) {
		if (src == ink) return flo;
		wint f;
		for (int &i = see[src]; ~i; i = next[i]) if (capa[i] > wEPS && lev[src] < lev[zu[i]]) {
			if ((f = augment(zu[i], ink, min(flo, capa[i]))) > wEPS) {
				capa[i] -= f; capa[i ^ 1] += f; return f;
			}
		}
		return 0;
	}
	bool solve(int src, int ink, wint flo = wINF) {
		wint f;
		int i, u, v;
		for (tof = 0; tof + wEPS < flo; ) {
			qb = qe = que;
			memset(lev, ~0, n * 4);
			for (lev[*qe++ = src] = 0, see[src] = ptr[src]; qb != qe; ) {
				for (i = ptr[u = *qb++]; ~i; i = next[i]) if (capa[i] > wEPS && !~lev[v = zu[i]]) {
					lev[*qe++ = v] = lev[u] + 1; see[v] = ptr[v];
					if (v == ink) goto au;
				}
			}
			return 0;
		au:	for (; (f = augment(src, ink, flo - tof)) > wEPS; tof += f);
		}
		return 1;
	}
}

int H, W, A[110][110];
int N;
int oriY[10101], endY[10101], col[10101];
vector<int> rem;
bool found[10101];

vector<int> decompose()
{
	MF::init(202);
	int s = 2 * H, t = 2 * H + 1;
	for (int v : rem) {
		MF::ae(oriY[v], endY[v] + H, 1);
	}
	for (int i = 0; i < H; ++i) {
		MF::ae(s, i, 1);
		MF::ae(i + H, t, 1);
	}
	MF::solve(s, t, H);
	vector<int> ret;
	for (int i = 0; i < H; ++i) {
		for (int e = MF::ptr[i]; e != -1; e = MF::next[e]) {
			if (MF::capa[e] == 0) {
				ret.push_back(rem[e / 2]);
				break;
			}
		}
	}
	for (int v : ret) found[v] = true;
	vector<int> rem2;
	for (int v : rem) if (!found[v]) rem2.push_back(v);
	rem = rem2;
	return ret;
}

int B[110][110], C[110][110];

int main()
{
	scanf("%d%d", &H, &W);
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			scanf("%d", &(A[i][j]));
			--A[i][j];
			//A[i][j] = H * W - 1 - (i * W + j);
		}
	}
	N = H * W;
	for (int i = 0; i < N; ++i) endY[i] = i / W;
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			oriY[A[i][j]] = i;
		}
	}
	for (int i = 0; i < N; ++i) rem.push_back(i);
	for (int i = 0; i < W; ++i) {
		auto d = decompose();
		//for (int v : d) printf("%d ", v); puts("");
		for (int v : d) col[v] = i;
	}
	for (int i = 0; i < N; ++i) {
		B[oriY[i]][col[i]] = i;
		C[endY[i]][col[i]] = i;
	}
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) printf("%d%c", B[i][j] + 1, j == W - 1 ? '\n' : ' ');
	}
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) printf("%d%c", C[i][j] + 1, j == W - 1 ? '\n' : ' ');
	}
	return 0;
}


Measured memory_bytes: 1528