#include<bits/stdc++.h>
using namespace std;
const int MAXN = 105;
const int MAXM = 1e4 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
int n, m, s, res[MAXN];
bool mat[MAXN][MAXN];
namespace NetworkFlow {
	const int INF = 2e9;
	const int MAXP = 205;
	struct edge {
		int dest, flow;
		unsigned pos;
	};
	vector <edge> a[MAXP];
	int tot, s, t, dist[MAXP];
	unsigned curr[MAXP];
	void addedge(int x, int y, int z) {
		a[x].push_back((edge) {y, z, a[y].size()});
		a[y].push_back((edge) {x, 0, a[x].size() - 1});
	}
	void init() {
		for (int i = 1; i <= n; i++) {
			a[i].clear();
			a[i + n].clear();
		}
		a[s = 2 * n + 1].clear();
		a[t = 2 * n + 2].clear();
		for (int i = 1; i <= n; i++) {
			addedge(s, i, 1);
			addedge(i + n, t, 1);
		} 
		for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (mat[i][j]) addedge(i, j + n, 1);
	}
	int dinic(int pos, int limit) {
		if (pos == t) return limit;
		int used = 0, tmp;
		for (unsigned &i = curr[pos]; i < a[pos].size(); i++)
			if (a[pos][i].flow != 0 && dist[pos] + 1 == dist[a[pos][i].dest] && (tmp = dinic(a[pos][i].dest, min(limit - used, a[pos][i].flow)))) {
				used += tmp;
				a[pos][i].flow -= tmp;
				a[a[pos][i].dest][a[pos][i].pos].flow += tmp;
				if (used == limit) return used;
			}
		return used;
	}
	bool bfs() {
		static int q[MAXP];
		int l = 0, r = 0;
		memset(dist, 0, sizeof(dist));
		dist[s] = 1, q[0] = s;
		while (l <= r) {
			int tmp = q[l];
			for (unsigned i = 0; i < a[tmp].size(); i++)
				if (dist[a[tmp][i].dest] == 0 && a[tmp][i].flow != 0) {
					q[++r] = a[tmp][i].dest;
					dist[q[r]] = dist[tmp] + 1;
				}
			l++;
		}
		return dist[t] != 0;
	}
	void flow() {
		int ans = 0;
		while (bfs()) {
			memset(curr, 0, sizeof(curr));
			ans += dinic(s, INF);
		}
		assert(ans == n);
		for (int i = 1; i <= n; i++) {
			for (auto x : a[i]) {
				if (x.dest != s && x.flow == 0) res[i] = x.dest - n;
			}
		}
	}
}
int a[MAXN][MAXN], b[MAXN][MAXN];
int f[MAXN][MAXN], g[MAXN][MAXN];
pair <int, int> home[MAXM];
vector <int> e[MAXN][MAXN]; 
int main() {
	read(n), read(m);
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++) {
		read(a[i][j]);
		home[a[i][j]].first = i;
		b[i][j] = ++s;
		home[b[i][j]].second = i;
	}
	for (int i = 1; i <= n * m; i++)
		e[home[i].first][home[i].second].push_back(i);
	for (int k = 1; k <= m; k++) {
		for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			mat[i][j] = e[i][j].size() != 0;
		NetworkFlow :: init();
		NetworkFlow :: flow();
		for (int i = 1; i <= n; i++) {
			int tmp = e[i][res[i]].back();
			e[i][res[i]].pop_back();
			f[i][k] = tmp;
			g[res[i]][k] = tmp;
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			printf("%d ", f[i][j]);
		printf("\n");
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++)
			printf("%d ", g[i][j]);
		printf("\n");
	}
	return 0;
}

Measured memory_bytes: 1536