#include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second

using vint=vector<int>;
using pint=pair<int,int>;
using vpint=vector<pint>;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
    ost<<"{"<<p.first<<","<<p.second<<"}";
    return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
    ost<<"{";
    for(int i=0;i<v.size();i++){
        if(i)ost<<",";
        ost<<v[i];
    }
    ost<<"}";
    return ost;
}

inline int topbit(unsigned long long x){
    return x?63-__builtin_clzll(x):-1;
}

inline int popcount(unsigned long long x){
    return __builtin_popcountll(x);
}

inline int parity(unsigned long long x){
    return __builtin_parity(x);
}


struct Dinic{
    using F=long long;
    static const F INF;

    struct Edge{
        int dst;
        F cap;
        int rev;
        Edge(int dst,F cap,int rev):dst(dst),cap(cap),rev(rev){}
    };

    int n;
    vector<vector<Edge>>G;
    vector<int>iter,level;
    Dinic(int n):n(n),G(n),iter(n),level(n){}
    inline void addEdge(int src,int dst,F cap){
        G[src].push_back(Edge(dst,cap,G[dst].size()));
        G[dst].push_back(Edge(src,0,G[src].size()-1));
    }
    inline void addUndirectedEdge(int src,int dst,F cap){
        G[src].push_back(Edge(dst,cap,G[dst].size()));
        G[dst].push_back(Edge(src,cap,G[src].size()-1));
    }

    void bfs(int s){
        level.assign(n,-1);
        queue<int>que;
        level[s]=0;
        que.push(s);
        while(que.size()){
            int u=que.front();
            que.pop();
            for(auto &e:G[u]){
                if(e.cap==0||level[e.dst]!=-1)continue;
                level[e.dst]=level[u]+1;
                que.push(e.dst);
            }
        }
    }

    F dfs(const int &s,const int &u,F cur){
        if(s==u)return cur;
        F sum=0;
        for(int &i=iter[u];i<G[u].size();i++){
            Edge &e=G[u][i],&ee=G[e.dst][e.rev];
            const int &v=e.dst;
            if(level[v]>=level[u]||ee.cap==0)continue;
            F f=dfs(s,v,min(cur-sum,ee.cap));
            if(f<=0)continue;
            ee.cap-=f;e.cap+=f;
            sum+=f;
            if(sum==cur)break;
        }
        return sum;
    }


    F maxFlow(int s,int t){
        F flow=0;
        while(true){
            bfs(s);
            if(level[t]==-1)return flow;
            iter.assign(n,0);
            flow+=dfs(s,t,INF);
        }
    }
};
const Dinic::F Dinic::INF=1ll<<50;

int N,M;
int A[111][111];
bool used[111][111];
int B[111][111];
signed main(){
    cin>>N>>M;
    rep(i,N)rep(j,M)cin>>A[i][j];

    rep(k,M){
        Dinic d(N+N+2);
        int src=2*N;
        int snk=src+1;
        rep(i,N)rep(j,M){
            if(used[i][j])continue;
            int h=(A[i][j]-1)/M;
            d.addEdge(i,N+h,1);
        }
        rep(i,N){
            d.addEdge(src,i,1);
            d.addEdge(i+N,snk,1);
        }
        d.maxFlow(src,snk);
        rep(i,N){
            int val;
            for(auto &e:d.G[i]){
                if(e.cap)continue;
                val=e.dst-N;
                break;
            }
            rep(j,M){
                if(used[i][j])continue;
                if((A[i][j]-1)/M!=val)continue;
                used[i][j]=true;
                B[i][k]=A[i][j];
                break;
            }
        }
    }

    rep(i,N){
        rep(j,M){
            if(j)cout<<" ";
            cout<<B[i][j];
        }
        cout<<endl;
    }

    rep(j,M){
        vint v(N);
        rep(i,N)v[i]=B[i][j];
        sort(all(v));
        rep(i,N)B[i][j]=v[i];
    }
    
    rep(i,N){
        rep(j,M){
            if(j)cout<<" ";
            cout<<B[i][j];
        }
        cout<<endl;
    }

    return 0;
}

Measured memory_bytes: 1160