#include <bits/stdc++.h>
using namespace std;
template<typename T> struct Dinitz{
	int n, source, sink;
	vector<vector<T>> adj;
	struct edge {
		int u;
		T flow, cap;
	};
	vector<edge> edges;
	Dinitz(int n, int source, int sink): n(n), source(source), sink(sink), adj(n) {}
	int add_edge(int a, int b, T abcap, T bacap = 0) {
		int result = edges.size();
		adj[a].push_back(edges.size());
		edges.push_back({b, 0, abcap});
		adj[b].push_back(edges.size());
		edges.push_back({a, 0, bacap});
		return result;
	}
	vector<int> mindist, position;
	bool bfs() {
		queue<int> q;
		fill(mindist.begin(), mindist.end(), INT_MAX / 2);
		mindist[source] = 0;
		q.push(source);
		while (!q.empty()) {
			int v = q.front();
			q.pop();
			for (int edid: adj[v]) {
				edge &ed = edges[edid];
				if (ed.flow < ed.cap && mindist[ed.u] > mindist[v] + 1) {
					mindist[ed.u] = mindist[v] + 1;
					q.push(ed.u);
				}
			}
		}
		return mindist[sink] < n;
	}
	T dfs(int v, T maxf) {
		if (v == sink) return maxf;
		for (int &pos = position[v]; pos < (int)adj[v].size(); ++pos) {
			int edid = adj[v][pos];
			edge &ed = edges[edid], &reved = edges[edid ^ 1];
			if (ed.flow < ed.cap && mindist[ed.u] == mindist[v] + 1) {
				T f = dfs(ed.u, min(maxf, ed.cap - ed.flow));
				if (f > 0) {
					ed.flow += f;
					reved.flow -= f;
					return f;
				}
			}
		}
		return 0;
	}
	T maxflow() {
		T result = 0;
		mindist.resize(n);
		position.resize(n);
		while (bfs()) {
			T extra;
			fill(position.begin(), position.end(), 0);
			do {
				extra = dfs(source, numeric_limits<T> :: max());
				result += extra;
			} while (extra > 0);
		}
		return result;
	}
};
const int maxn = 111;
int g[maxn][maxn];
int cnt[maxn][maxn];
int res[maxn][maxn];
vector<int> ready[maxn][maxn];
int main(){
	int n, m; cin >> n >> m;
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> g[i][j];
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) g[i][j]--;
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cnt[i][g[i][j] / m]++;
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) ready[i][g[i][j] / m].push_back(g[i][j]);
	for(int i = 0; i < m; i++){
		int nds = 0;
		int source = nds++;
		vector<int> wh(n), bl(n);
		for(int j = 0; j < n; j++){
			wh[j] = nds++;
			bl[j] = nds++;
		}
		int sink = nds++;
		Dinitz<int> dinic(nds, source, sink);
		for(int j = 0; j < n; j++){
			dinic.add_edge(source, wh[j], 1);
			dinic.add_edge(bl[j], sink, 1);
			for(int k = 0; k < n; k++){
				if(cnt[j][k]){
					dinic.add_edge(wh[j], bl[k], 1);
				}
			}
		}
		assert(dinic.maxflow() == n);
		for(int j = 0; j < n; j++){
			for(int k = 0; k < n; k++){
				for(int id : dinic.adj[wh[j]]){
					int u = dinic.edges[id].u;
					int flow = dinic.edges[id].flow;
					int cap = dinic.edges[id].cap;
					if(flow > 0 && flow == cap){
						if(u == bl[k]){
							res[j][i] = ready[j][k].back();
							ready[j][k].pop_back();
							cnt[j][k]--;
						}
					}
				}
			}
		}
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) printf("%d%c", res[i][j] + 1, " \n"[j + 1 == m]);
	for(int i = 0; i < m; i++){
		vector<int> tmp;
		for(int j = 0; j < n; j++) tmp.push_back(res[j][i]);
		sort(tmp.begin(), tmp.end());
		for(int j = 0; j < n; j++) res[j][i] = tmp[j];
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) printf("%d%c", res[i][j] + 1, " \n"[j + 1 == m]);
	return 0;
}


Measured memory_bytes: 1636