#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

class Edge {
public:
	long long int to;
	long long int max_flow;
	long long int rev;
	int idx;
	bool flag;
};

class Dinic {
	int V;
	bool directed;
public:
	vector<vector<Edge>>edge;
	vector<int>depth;
	vector<int>index;
	Dinic(int n, bool D) {
		n++;
		V = n;
		edge.resize(V);
		depth.resize(V);
		index.resize(V);
		directed = D;
		return;
	}
	void Add_Edge(int l, int r, int max_flow,int idx) {
		edge[l].push_back({ r,max_flow,(int)edge[r].size() ,idx,true});
		if (directed) {
			edge[r].push_back({ l,0,(int)edge[l].size() - 1,idx,false });
		}
		else {
			edge[r].push_back({ l,max_flow,(int)edge[l].size() - 1,idx,false });
		}
		return;
	}
	void Check_Depth(int s) {
		for (int i = 0; i < V; i++) {
			depth[i] = INT_MAX;
		}
		depth[s] = 0;
		queue<int>Q;
		Q.push(s);
		while (!Q.empty()) {
			int cn = Q.front();
			Q.pop();
			for (auto i : edge[cn]) {
				if (i.max_flow > 0 && depth[i.to] == INT_MAX) {
					depth[i.to] = depth[cn] + 1;
					Q.push(i.to);
				}
			}
		}
		return;
	}
	long long int max_flow(int v, int g, long long int ret) {
		if (v == g) {
			return ret;
		}
		for (int i = index[v]; i < edge[v].size(); i++) {
			if (edge[v][i].max_flow > 0 && depth[v] < depth[edge[v][i].to]) {
				long long int d = max_flow(edge[v][i].to, g, min(ret, edge[v][i].max_flow));
				if (d > 0) {
					edge[v][i].max_flow -= d;
					edge[edge[v][i].to][edge[v][i].rev].max_flow += d;
					return d;
				}
			}
		}
		return 0;
	}
	long long Solve(int s, int g) {
		long long int ret = 0;
		while (1) {
			Check_Depth(s);
			if (depth[g] == INT_MAX) {
				return ret;
			}
			for (int i = 0; i < V; i++) {
				index[i] = 0;
			}
			long long int add = 0;
			while ((add = max_flow(s, g, INT_MAX)) > 0) {
				ret += add;
			}
		}
		return ret;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> H >> W;
	vector<vector<int>>v(H, vector<int>(W));
	vector<vector<int>>used(H, vector<int>(W));
	vector<pair<int, int>>p(H*W + 1);
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> v[i][j];
			p[v[i][j]] = { i,j };
		}
	}
	vector<vector<int>>w(H, vector<int>(W));
	for (int loop = 0; loop < W; loop++) {
		Dinic d(H*W + 2,true);
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				if (used[i][j])continue;
				d.Add_Edge(i, H + (v[i][j] - 1) / W, 1, v[i][j]);
			}
			d.Add_Edge(H * 2, i, 1, 0);
			d.Add_Edge(i + H, H * 2 + 1, 1, 0);
		}
		d.Solve(H * 2, H * 2 + 1);
		for (auto i : d.edge) {
			for (auto j : i) {
				if (j.flag&&j.idx&&j.max_flow == 0) {
					used[p[j.idx].first][p[j.idx].second] = 1;
					w[p[j.idx].first][loop] = j.idx;
				}
			}
		}
	}
	for (auto i : w) {
		for (auto j : i) {
			cout << j << " ";
		}
		cout << endl;
	}
	for (int i = 0; i < H; i++) {
		for (int j = i + 1; j < H; j++) {
			for (int k = 0; k < W; k++) {
				if (w[i][k] > w[j][k])swap(w[i][k], w[j][k]);
			}
		}
	}
	for (auto i : w) {
		for (auto j : i) {
			cout << j << " ";
		}
		cout << endl;
	}
}

Measured memory_bytes: 1744