// Code by H~$~C
#warning "Code by H~$~C, don't copy it!"

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h> // assume the OJ isn't POJ
#define __str__(...) #__VA_ARGS__
#define __cat__(x, y) x##y
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = (1); i <= (n); ++i)
#define Rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, n) for (int i = ((n) - 1); ~i; --i)
#define per1(i, n) for (int i = (n); i; --i)
#define Per(i, a, b) for (int i = (a); i >= (b); --i)
#define repit(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define eprintf(...) (fprintf(stderr, __VA_ARGS__) & fflush(stderr))
#define scanfstr(s, len, ...) { static char _str[len + 1]; scanf(__VA_ARGS__, _str); s = _str; }
#define rdstr(s, len) { static char _str[len + 1]; scanf("%s", _str); s = _str; }
#define getstr(s, len) { static char _str[len + 1]; fgets(_str, len, stdin); s = _str; s.pop_back(); }
#define scanfignore() scanf(" ")
#define fillset(a, val) memset(a, val, sizeof(a))
#define All(a) a.begin(), a.end()
#define SZ(a) ((int)a.size())
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pf push_front
#define y0 y19260817
#define y1 y19268107
#define j0 j19260817
#define j1 j19268107
#define x0 x19260817
#define x1 x19268107
using namespace std;
#ifndef LOCAL_JUDGE
#define Debug(...)
#else
template <typename T> inline void _debug(const char *names, T &&t) {
(cerr << names << " = " << t << endl).flush();}
template <typename T1, typename ...T>
inline void _debug(const char *names, T1 &&t1, T &&... t) {
const char *comma = strchr(names, ',');
(cerr.write(names, comma - names) << " = " << t1 << ", ").flush();
_debug(comma + 1, t ...);}
#define Debug(...) _debug(#__VA_ARGS__, __VA_ARGS__)
#endif
struct __STARTER_OF_PROGRAM__ { __STARTER_OF_PROGRAM__() {
  cerr << "Code by H~$~C: \n" << flush;
} } __starter_of_program__;
struct __ENDDER_OF_PROGRAM__ { ~__ENDDER_OF_PROGRAM__() {
#ifdef LOCAL_JUDGE
  cerr << fixed << setprecision(3);
  cerr << "\n\nTime elapsed: " << clock() * 1000.0 / CLOCKS_PER_SEC << " ms\n" << flush;
#endif
} } __endder_of_program__;

template <typename T> using min_queue = priority_queue <T, vector <T>, greater <T> >;
template <typename T> using max_queue = priority_queue <T>;
#if __cplusplus <= 201403L
template <typename ...T> using void_t = void;
#endif
template <typename T> inline T chmax(T &x, T y) { return x = max(x, y); }
template <typename T> inline T chmin(T &x, T y) { return x = min(x, y); }
template <typename T> inline T chmax(T &x, initializer_list <T> i) { return x = max(x, max(i)); }
template <typename T> inline T chmin(T &x, initializer_list <T> i) { return x = min(x, min(i)); }
template <typename T> inline void reinit(T &t) { t.~T(); new (&t) T(); }
mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
const double EPS = 1e-9, PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;

const int Maxn = 205;
const int Maxm = 40005;

namespace DINIC { // Max Flow
	struct Edge {
		int to;
		long long dis; 
		int nxt;
	} e[Maxm << 1];
	int head[Maxn], cnt;
	inline void clear() {
		memset(head, 0, sizeof (head));
		cnt = 1; 
	}
	inline void add_edge(int u, int v, long long flow) {
		e[++cnt] = (Edge){v, flow, head[u]}, head[u] = cnt;
		e[++cnt] = (Edge){u, 0, head[v]}, head[v] = cnt;
	}
	int dis[Maxn], cur[Maxn];
	int que[Maxn], qh, qe;
	bool bfs(int s, int t) {
		memset(dis, 0, sizeof (dis));
		memcpy(cur, head, sizeof (cur));
		qh = qe = 0, que[qe++] = s;
		dis[s] = 1;
		while (qh < qe) {
			int u = que[qh++], v;
			for (int i = head[u]; i; i = e[i].nxt)
				if (!dis[v = e[i].to] && e[i].dis)
					dis[v] = dis[u] + 1, que[qe++] = v;
		}
		return dis[t];
	}
	long long dfs(int u, int t, long long limit) {
		if (u == t || !limit) return limit;
		int v; long long res = 0, p;
		for (int &i = cur[u]; i && limit; i = e[i].nxt)
			if (dis[v = e[i].to] == dis[u] + 1 && e[i].dis > 0) {
				p = dfs(v, t, min(limit, e[i].dis));
				e[i].dis -= p, e[i ^ 1].dis += p, res += p;
				if (res >= limit) break;
			}
		return res;
	}
	long long dinic(int s, int t) {
		long long res = 0;
		while (bfs(s, t))
			res += dfs(s, t, 0x3f3f3f3f3f3f3f3f);
		return res;
	}
}

int n, m;
int a[105][105], b[105][105];
int c[105], bl[105];
vector <int> v[105][105];

int main(int argc, const char *argv[]) {
  scanf("%d %d", &n, &m);
  rep1(i, n) rep1(j, m) {
    scanf("%d", a[i] + j);
    v[i][(a[i][j] - 1) / m].push_back(a[i][j]); 
  }
  rep1(j, m) {
    DINIC::clear();
    static const int S = 2 * n + 3, T = 2 * n + 4;
    rep1(i, n) DINIC::add_edge(S, i, 1);
    rep(k, n) DINIC::add_edge(k + n + 1, T, 1);
    rep1(i, n) rep(k, n)
      DINIC::add_edge(i, k + n + 1, SZ(v[i][k]));
    int mxflow = DINIC::dinic(S, T);
    Debug(mxflow);
    fillset(bl, inf);
    rep1(i, n) {
      for (int h = DINIC::head[i]; h; h = DINIC::e[h].nxt) {
        int to = DINIC::e[h].to, flow = DINIC::e[h].dis;
        if (to != S && flow != SZ(v[i][to - n - 1])) bl[i] = to - n - 1;
      }
      assert(bl[i] != inf);
      b[i][j] = v[i][bl[i]].back();
      v[i][bl[i]].pop_back();
    } 
  }
  rep1(i, n) rep1(j, m)
    printf("%d%c", b[i][j], " \n"[j == m]);
  rep1(j, m) {
    rep1(i, n) c[i] = b[i][j];
    sort(c + 1, c + n + 1);
    rep1(i, n) b[i][j] = c[i];
  }
  rep1(i, n) rep1(j, m)
    printf("%d%c", b[i][j], " \n"[j == m]);
  return 0;
}


Measured memory_bytes: 1536