#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <array>
#include <bitset> 
#include <unordered_map>
#include <random>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
struct Edge
{
	int a;
	int b;
	int c;
	int f;
	int ob;
};
template<int S>
struct Flow
{
vector<Edge> es;
vector<int> edges[S];
void add(int a, int b, int cap, int p){
	//cout << "add " << a << ", " << b << ", " << cap << endl;
	es.push_back(Edge());
	Edge& e=es.back();
	e.a=a;
	e.b=b;
	e.c=cap;
	e.f=0;
	e.ob=p;
	edges[a].push_back(es.size()-1);
	edges[b].push_back(es.size()-1);
}
void init(){
	es.clear();
	for(int i=0;i<S;i++){
		edges[i].clear();
	}
}
int fill(int s, int t, int sz=S){
	int ret=0;
	int pre[S];
	int Q[S];
	while(1){
		memset(pre,-1,sizeof(int)*sz);
		int qs=0;
		Q[0]=s;
		pre[s]=-2;
		int qe=1;
		while(qs<qe&&pre[t]==-1){
			int p=Q[qs++];
			for(int i=0;i<edges[p].size();i++){
				int j=edges[p][i];
				int nex;
				if(es[j].a==p){
					if(es[j].f==es[j].c){
						continue;
					}
					nex=es[j].b;
				}
				else{
					if(es[j].f==0){
						continue;
					}
					nex=es[j].a;
				}
				if(pre[nex]==-1){
					Q[qe++]=nex;
					pre[nex]=j;
				}
			}
		}
		if(pre[t]==-1){
			return ret;
		}
		{
			int p=t;
			int f=INT_MAX;
			while(p!=s){
				int j=pre[p];
				if(es[j].b==p){
					f=min(f,es[j].c - es[j].f);
					p=es[j].a;
				}
				else{
					f=min(f,es[j].f);
					p=es[j].b;
				}
			}
			p=t;
			while(p!=s){
				int j=pre[p];
				if(es[j].b==p){
					es[j].f+=f;
					p=es[j].a;
				}
				else{
					es[j].f-=f;
					p=es[j].b;
				}
			}
			ret+=f;
		}
	}
	// ここには来ない
	return -1;
}
};
int b[100][100];
int c[100][100];
bool solve(long long N, long long M, std::vector<std::vector<long long>> A){
	Flow<202> flow;
	int s=2*N;
	int t=s+1;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			int a=(A[i][j]-1)/M;
			flow.add(i,N+a,1,A[i][j]);
		}
		flow.add(s,i,1,0);
		flow.add(i+N,t,1,0);
	}
	for(int j=0;j<M;j++){
		flow.fill(s,t);
		for(int k=0;k<flow.es.size();k++){
			Edge& e=flow.es[k];
			if(e.f)
			{
				if(e.ob){
					b[e.a][j]=e.ob;
					c[e.b-N][j]=e.ob;
					e.f=0;
					e.c=0;
				}
				else{
					e.f=0;
					e.c=1;
				}
			}
		}
	}

	for(int i=0;i<N;i++){
		auto sp="";
		for(int j=0;j<M;j++){
			cout << sp << b[i][j];
			sp=" ";
		}
		cout << endl;
	}
	for(int i=0;i<N;i++){
		auto sp="";
		for(int j=0;j<M;j++){
			cout << sp << c[i][j];
			sp=" ";
		}
		cout << endl;
	}
	return true;
}

int main(){
#if 1
    long long N;
    scanf("%lld",&N);
    long long M;
    scanf("%lld",&M);
    std::vector<std::vector<long long>> A(N, std::vector<long long>(M));
    for(int i = 0 ; i < N ; i++){
        for(int j = 0 ; j < M ; j++){
            scanf("%lld",&A[i][j]);
        }
    }

    solve(N, M, std::move(A));
#else
	int N=9,M=10;
	vector<int> s;
	for(int i=1;i<=N*M;i++){
		s.push_back(i);
	}
	shuffle (s.begin(), s.end(), std::default_random_engine(100));
    std::vector<std::vector<long long>> A(N, std::vector<long long>(M));
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			A[i][j]=s[M*i+j];
			cout << A[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
	cout << solve(N,M,move(A));
    return 0;
#endif
}


Measured memory_bytes: 4004