#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <set>
 
using namespace std;
typedef long long ll;
const int MAXN = 110;

struct DfsMatch
{
    const static int MAXA = MAXN, MAXB = MAXN, INF = 1000000005;

    int A, B, elast [MAXA];
    int start, vis [MAXA], prev [MAXB];
    vector <int> eadj, eprev;

    inline DfsMatch ()
    {
        A = B = -1;
    }

    inline void init (int a, int b)
    {
        A = a; B = b;
        for (int i = 0; i < MAXA; i++)
            elast[i] = -1;
        eadj.clear ();
        eprev.clear ();
    }

    inline void addedge (int a, int b)
    {
        eadj.push_back (b); eprev.push_back (elast [a]); elast [a] = eprev.size() - 1;
    }

    bool dfs (int num)
    {
        if (vis [num] == start)
            return false;

        vis [num] = start;

        for (int i = elast [num]; i != -1; i = eprev [i])
            if (prev [eadj [i]] == -1)
            {
                prev [eadj [i]] = num;
                return true;
            }

        for (int i = elast [num]; i != -1; i = eprev [i])
            if (dfs (prev [eadj [i]]))
            {
                prev [eadj [i]] = num;
                return true;
            }

        return false;
    }

    int match ()
    {
        if (A == -1 && B == -1)
            return -INF;

        for (int i = 0; i < MAXA; i++)
            prev[i] = vis[i] = -1;
        int total = 0;

        for (int i = 0; i < A; i++)
        {
            start = i;

            if (dfs (i))
                total++;
        }

        return total;
    }
};

int N, M;
int arr[MAXN][MAXN];
int nv[MAXN][MAXN]; // num values of row j in row i

int gv (int x)
{
    return (x - 1) / M;
}

int nc[MAXN];

int nnext[MAXN];

void get_match()
{
    DfsMatch s;
    s.init(N, N);
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (nv[i][j] > 0)
                s.addedge(i, j);
    s.match();
    for (int i = 0; i < N; i++)
        nnext[s.prev[i]] = i;

    //for (int i = 0; i < N; i++)
    //    cout << nnext[i] << " ";
    //cout << "\n";
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin >> N >> M;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++)
        {
            cin >> arr[i][j];
            nv[i][gv(arr[i][j])]++;
        }

    for (int j = 0; j < M; j++)
    {
        get_match();
        for (int i = 0; i < N; i++)
        {
            int g = nnext[i];
            for (int k = j; k < M; k++)
                if (gv(arr[i][k]) == g)
                {
                    swap (arr[i][j], arr[i][k]);
                    break;
                }
            if (gv(arr[i][j]) != g)
            {
                cout << "FUCK\n";
            }
            nv[i][g]--;
        }
    }

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (j) cout << " ";
            cout << arr[i][j];
        }
        cout << "\n";
    }

    for (int j = 0; j < M; j++)
    {
        for (int i = 0; i < N - 1; i++)
        {
            for (int k = 0; k < N - 1; k++)
            {
                if (arr[k][j] > arr[k+1][j])
                    swap (arr[k][j], arr[k+1][j]);
            }
        }
    }

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (j) cout << " ";
            cout << arr[i][j];
        }
        cout << "\n";
    }
}

Measured memory_bytes: 600