Problem:
Score : 1100 points

Problem Statement

We have a grid with N rows and M columns of squares.
Each integer from 1 to NM is written in this grid once.
The number written in the square at the i-th row from the top and the j-th column from the left is A_{ij}.

You need to rearrange these numbers as follows:

First, for each of the N rows, rearrange the numbers written in it as you like.

Second, for each of the M columns, rearrange the numbers written in it as you like.

Finally, for each of the N rows, rearrange the numbers written in it as you like.

After rearranging the numbers, you want the number written in the square at the i-th row from the top and the j-th column from the left to be M\times (i-1)+j.
Construct one such way to rearrange the numbers. The constraints guarantee that it is always possible to achieve the objective.

Constraints

1 \leq N,M \leq 100

1 \leq A_{ij} \leq NM

A_{ij} are distinct.

Input

Input is given from Standard Input in the following format:

N M
A_{11} A_{12} ... A_{1M}
:
A_{N1} A_{N2} ... A_{NM}

Output

Print one way to rearrange the numbers in the following format:

B_{11} B_{12} ... B_{1M}
:
B_{N1} B_{N2} ... B_{NM}
C_{11} C_{12} ... C_{1M}
:
C_{N1} C_{N2} ... C_{NM}

Here B_{ij} is the number written in the square at the i-th row from the top and the j-th column from the left after Step 1, and C_{ij} is the number written in that square after Step 2.

Sample Input 1

3 2
2 6
4 3
1 5

Sample Output 1

2 6
4 3
5 1
2 1
4 3
5 6

Sample Input 2

3 4
1 4 7 10
2 5 8 11
3 6 9 12

Sample Output 2

1 4 7 10
5 8 11 2
9 12 3 6
1 4 3 2
5 8 7 6
9 12 11 10

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

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

typedef long long ll;
typedef double lf;
typedef long double Lf;
typedef pair <int,int> pii;
typedef pair <ll, ll> pll;

#define TRACE(x) cerr << #x << "  " << x << endl
#define FOR(i, a, b) for (int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define _ << " " <<

#define fi first
#define sec second
#define mp make_pair
#define pb push_back

typedef vector <vector <int> > mat;

const int MAXN = 510;

struct Matching {
  vector <int> v[MAXN * 10];
  vector <int> par, bio;
  int n, m;

  void init(int _n, int _m) {
    n = _n;
    m = _m;
    bio.clear();
    par.clear();
    REP(i, 2 * max(n, m)) {
      v[i].clear();
    }
  }

  int upari(int cvor) {
    bio[cvor] = 1;

    REP(i, (int)v[cvor].size()) {
      int ncvor = v[cvor][i];
      if (par[ncvor] == -1) {par[ncvor] = cvor; return 1;}
      if (bio[par[ncvor]]) continue;
      if (upari(par[ncvor])) {par[ncvor] = cvor; return 1;}
    }
    return 0;
  }

  void edge(int a, int b) {
    v[a].pb(b + n);
    v[b + n].pb(a);
  }

  vector <int> run() {
    int sol = 0;
    par.clear();
    par.resize(2 * max(n, m), -1);
    REP(i, n) {
      bio.clear();
      bio.resize(2 * max(n, m), 0);
      sol += upari(i);
    }
    REP(i, 2 * max(n, m)) v[i].clear();
    return par;
  }
}M;

int n, m;

mat p, kraj, uzet;
vector <mat> ans, ans1;

void myassert(bool ok) {
  if (!ok) exit(0);
  return;
}

void print(mat &pr) {
  set <int> prov;
  REP(i, n) {
    REP(j, m) {
      printf("%d ",pr[i][j] + 1);
      assert(prov.count(pr[i][j]) == 0);
      myassert(pr[i][j] >= 0 && pr[i][j] <= n * m-1);
      prov.insert(pr[i][j]);
    }
    puts("");
  }
}

int cnt_col[MAXN][MAXN];

void init() {
  kraj.clear();
  p.clear();
  ans.clear();
  ans1.clear();
  uzet.clear();
  kraj.resize(n, vector <int>(m, 0));
  p.resize(n, vector<int>(m, 0));
  uzet.resize(n, vector<int>(m, 0));
  REP(i, n + 1) REP(j, m + 1) cnt_col[i][j] = 0;
}

bool check2() {
  bool ok = 1;
  mat p1 = p;
  vector <int> per(m, 0);
  REP(i, m) per[i] = i;
  REP(i, n) {
    vector <int> t;
    REP(j, m) t.pb(p[i][j] % m);
    sort(all(t));
    if (t != per) ok = 0;
  }
  if (!ok) return false;
  
  REP(i, n) {
    vector <pii> t;
    REP(j, m) t.pb({p[i][j] % m, p[i][j]});
    sort(all(t));
    REP(j, m) p[i][j] = t[j].sec;
  }

  if (p1 != p) ans1.pb(p);
  if (p != kraj) ans1.pb(kraj);

  if (ans.empty() || ans1.size() < ans.size()) ans = ans1;

  return true;
}

void solve() {
  scanf("%d %d",&n,&m);
  init();
  REP(i, n) {
    REP(j, m) {
      kraj[i][j] = i * m + j;
      scanf("%d",&p[i][j]);
      p[i][j]--;
      cnt_col[j][p[i][j] / m]++;
    }
  }

  
  if (p == kraj) {
    puts("0");
    return;
  }

  bool ok = 1;
  REP(i, n) {
    REP(j, m) {
      if (cnt_col[i][j] != 1) ok = 0;
    }
  }

  mat last = p;
  if (ok) {
    mat p1 = p;
    REP(j, m) {
      vector <int> tu;
      REP(i, n) tu.pb(p[i][j]);
      sort(all(tu));
      REP(i, n) p[i][j] = tu[i];
    }
    if (p != p1) ans.pb(p);
    if (p != kraj) ans.pb(kraj);
  }
  p = last;

  if (check2() || ok) {
    //printf("%d\n",(int)ans.size());
  if (ans.size() > 2) ans.pop_back();
  if (ans.size() == 1) ans.pb(kraj);
    for (auto &t : ans) print(t);
    return;
  }

  p = last;

  mat pom;
  pom.resize(n, vector<int>(m, 0));


  REP(col, m) {
    M.init(n, n);
    set <int> fiks;
    REP(i, n) if (kraj[i][col] == p[i][col]) fiks.insert(i);
    REP(i, n) {
      vector <int> color(n, -1);
      if (fiks.count(i)) {
        M.edge(i, p[i][col] / m);
        pom[i][col] = p[i][col];
        continue;
      }
      REP(j, m) {
        if (uzet[i][j] || color[p[i][j] / m] != -1 || kraj[i][j] == p[i][j]) continue;
        color[p[i][j] / m] = p[i][j];
        M.edge(i, p[i][j] / m);
      }
    }
    auto par = M.run();
    REP(i, n) {
      vector <int> color(n, -1);
      if (fiks.count(i)) continue;
      REP(j, m) {
        if (uzet[i][j] || color[p[i][j] / m] != -1 || kraj[i][j] == p[i][j]) continue;
        if (par[p[i][j]/m+n] != i) continue;
        color[p[i][j] / m] = p[i][j];
        pom[i][col] = p[i][j];
        uzet[i][j] = 1;
      }
    }
  }

  ans.pb(pom);
  mat p1 = pom;
  REP(j, m) {
    vector <int> tu;
    REP(i, n) tu.pb(pom[i][j]);
    sort(all(tu));
    REP(i, n) pom[i][j] = tu[i];
  }
  if (p1 != pom) ans.pb(pom);
  if (pom != kraj) ans.pb(kraj);
  //printf("%d\n",(int)ans.size());
  if (ans.size() > 2) ans.pop_back();
  if (ans.size() == 1) ans.pb(kraj);
  for (auto &t : ans) print(t);
}

int main() {
  int t;
  //scanf("%d",&t);
  t = 1;
  while (t--) solve();
  return 0;
}