#include <cstdio>
#include <algorithm>

using namespace std;
const int Max_NM(105);
const int INF(0X3F3F3F3F);

namespace io
{
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	inline void flush (){fwrite (obuf, 1, oS - obuf, stdout);oS = obuf;}
	inline void putc (char x){*oS ++ = x;if (oS == oT) flush ();}
	template <class I>
	inline void gi (I &x) {for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;}
	template <class I>
	inline void print (I x){
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;while(x) qu[++ qr] = x % 10 + '0',  x /= 10;while (qr) putc (qu[qr--]);}
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io::gi;
using io::putc;
using io::print;

namespace G
{
	const int Max_V(300000);
	const int Max_E(3000000);
	int V, S, T, Head[Max_V], Total, To[Max_E], Next[Max_E], Cap[Max_E], Flow[Max_E];
	inline void Add_Edge(int tot, int s, int t, int c)
	{
		To[tot] = t, Next[tot] = Head[s], Head[s] = tot, Cap[tot] = c, Flow[tot] = 0;
	}
	inline void Add_Link(int s, int t, int c)
	{
		Total += 2, Add_Edge(Total, s, t, c), Add_Edge(Total ^ 1, t, s, 0);
	}
	void clear()
	{
		for (int i = 1;i <= V;++i)
			Head[i] = 0;
		for (int i = 2;i <= Total + 1;++i)
			To[i] = Next[i] = Cap[i] = Flow[i] = 0;
		V = S = T = Total = 0;
	}
	int Cur[Max_V], Q[Max_V], Dist[Max_V];
	bool BFS()
	{
		int l, r;
		for (int i = 1;i <= V;++i)
			Dist[i] = 0;
		Dist[Q[l = r = 1] = S] = 1;
		for (int u;l <= r;)
		{
			if ((u = Q[l++]) == T)
				return true;
			for (int i = Head[u], v;i;i = Next[i])
				if (!Dist[v = To[i]] && Cap[i] > Flow[i])
					Dist[Q[++r] = v] = Dist[u] + 1;
		}
		return false;
	}
	int DFS(int u, int a)
	{
		if (u == T || a == 0)
			return a;
		int Ans(0);
		for (int &i = Cur[u], v, f;i;i = Next[i])
			if (Dist[v = To[i]] == Dist[u] + 1 && (f = DFS(v, min(a, Cap[i] - Flow[i]))) > 0)
			{
				Ans += f, Flow[i] += f, Flow[i ^ 1] -= f;
				if ((a -= f) == 0)
					break;
			}
		return Ans;
	}
	int Dinic()
	{
		int Ans(0);
		while (BFS())
		{
			for (int i = 1;i <= V;++i)
				Cur[i] = Head[i];
			Ans += DFS(S, INF);
		}
		return Ans;
	}
}

int N, M, A[Max_NM][Max_NM], P[Max_NM];

int main()
{
	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 j = 1;j <= M;++j)
	{
		G::clear();
		G::V = N + N + 2, G::S = N + N + 1, G::T = N + N + 2;
		for (int i = 1;i <= N;++i)
			G::Add_Link(G::S, i, +1), G::Add_Link(N + i, G::T, +1);
		for (int i = 1;i <= N;++i)
			for (int k = j;k <= M;++k)
				G::Add_Link((A[i][k] - 1) / M + 1, N + i, 1);
		G::Dinic();
		for (int i = 1, now = N * 2 * 2;i <= N;++i)
			for (int k = j;k <= M;++k)
			{
				now += 2;
				if (G::Flow[now] == 1)
					swap(A[i][j], A[i][k]);
			}
	}
	for (int i = 1;i <= N;++i)
	{
		for (int j = 1;j <= M;++j)
			print(A[i][j]), putc(' ');
		putc('\n');
	}
	for (int j = 1;j <= M;++j)
	{
		for (int i = 1;i <= N;++i)
			P[i] = A[i][j];
		sort(P + 1, P + 1 + N);
		for (int i = 1;i <= N;++i)
			A[i][j] = P[i];
	}
	for (int i = 1;i <= N;++i)
	{
		for (int j = 1;j <= M;++j)
			print(A[i][j]), putc(' ');
		putc('\n');
	}
	return 0;
}

Measured memory_bytes: 12672