#include <bits/stdc++.h>
using namespace std;
using ll = std::int_fast64_t;
using P = pair<ll, ll>;
constexpr ll inf = 1000000000;
constexpr ll mod = 998244353;
constexpr long double eps = 1e-15;
template <typename T1, typename T2>
ostream& operator<<(ostream& os, pair<T1, T2> p) {
  os << to_string(p.first) << " " << to_string(p.second);
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
  for (ll i = 0; i < (int)v.size(); i++) {
    if (i) os << " ";
    os << to_string(v[i]);
  }
  return os;
}
struct modint {
  ll n;

 public:
  modint(const ll n = 0) : n((n % mod + mod) % mod) {}
  static modint pow(modint a, int m) {
    modint r = 1;
    while (m > 0) {
      if (m & 1) {
        r *= a;
      }
      a = (a * a);
      m /= 2;
    }
    return r;
  }
  modint& operator++() {
    *this += 1;
    return *this;
  }
  modint& operator--() {
    *this -= 1;
    return *this;
  }
  modint operator++(int) {
    modint ret = *this;
    *this += 1;
    return ret;
  }
  modint operator--(int) {
    modint ret = *this;
    *this -= 1;
    return ret;
  }
  modint operator~() const { return (this->pow(n, mod - 2)); }
  friend bool operator==(const modint& lhs, const modint& rhs) {
    return lhs.n == rhs.n;
  }
  friend bool operator<(const modint& lhs, const modint& rhs) {
    return lhs.n < rhs.n;
  }
  friend bool operator>(const modint& lhs, const modint& rhs) {
    return lhs.n > rhs.n;
  }
  friend modint& operator+=(modint& lhs, const modint& rhs) {
    lhs.n += rhs.n;
    if (lhs.n >= mod) lhs.n -= mod;
    return lhs;
  }
  friend modint& operator-=(modint& lhs, const modint& rhs) {
    lhs.n -= rhs.n;
    if (lhs.n < 0) lhs.n += mod;
    return lhs;
  }
  friend modint& operator*=(modint& lhs, const modint& rhs) {
    lhs.n = (lhs.n * rhs.n) % mod;
    return lhs;
  }
  friend modint& operator/=(modint& lhs, const modint& rhs) {
    lhs.n = (lhs.n * (~rhs).n) % mod;
    return lhs;
  }
  friend modint operator+(const modint& lhs, const modint& rhs) {
    return modint(lhs.n + rhs.n);
  }
  friend modint operator-(const modint& lhs, const modint& rhs) {
    return modint(lhs.n - rhs.n);
  }
  friend modint operator*(const modint& lhs, const modint& rhs) {
    return modint(lhs.n * rhs.n);
  }
  friend modint operator/(const modint& lhs, const modint& rhs) {
    return modint(lhs.n * (~rhs).n);
  }
};
istream& operator>>(istream& is, modint m) {
  is >> m.n;
  return is;
}
ostream& operator<<(ostream& os, modint m) {
  os << m.n;
  return os;
}
long long extgcd(long long a, long long b, long long& x, long long& y) {
  long long d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}
long long mod_inverse(long long a, long long m) {
  long long x, y;
  if (extgcd(a, m, x, y) == 1)
    return (m + x % m) % m;
  else
    return -1;
}
vector<long long> fact(3030303 + 1, inf);
long long mod_fact(long long n, long long& e) {
  if (fact[0] == inf) {
    fact[0] = 1;
    if (3030303 != 0) fact[1] = 1;
    for (ll i = 2; i <= 3030303; ++i) {
      fact[i] = (fact[i - 1] * i) % mod;
    }
  }
  e = 0;
  if (n == 0) return 1;
  long long res = mod_fact(n / mod, e);
  e += n / mod;
  if ((n / mod) % 2 != 0) return (res * (mod - fact[n % mod])) % mod;
  return (res * fact[n % mod]) % mod;
}
long long mod_comb(long long n, long long k) {
  if (n < 0 || k < 0 || n < k) return 0;
  long long e1, e2, e3;
  long long a1 = mod_fact(n, e1), a2 = mod_fact(k, e2),
            a3 = mod_fact(n - k, e3);
  if (e1 > e2 + e3) return 0;
  return (a1 * mod_inverse((a2 * a3) % mod, mod)) % mod;
}
class HopcroftKarp {
 public:
  vector<vector<int>> graph;
  vector<int> dist, match;
  vector<bool> used, vv;
  HopcroftKarp(int n, int m) : graph(n), match(m, -1), used(n) {}
  void add_edge(int u, int v) { graph[u].push_back(v); }
  void bfs() {
    dist.assign(graph.size(), -1);
    queue<int> que;
    for (int i = 0; i < graph.size(); i++) {
      if (!used[i]) {
        que.emplace(i);
        dist[i] = 0;
      }
    }
    while (!que.empty()) {
      int a = que.front();
      que.pop();
      for (auto& b : graph[a]) {
        int c = match[b];
        if (c >= 0 && dist[c] == -1) {
          dist[c] = dist[a] + 1;
          que.emplace(c);
        }
      }
    }
  }
  bool dfs(int a) {
    vv[a] = true;
    for (auto& b : graph[a]) {
      int c = match[b];
      if (c < 0 || (!vv[c] && dist[c] == dist[a] + 1 && dfs(c))) {
        match[b] = a;
        used[a] = true;
        return (true);
      }
    }
    return (false);
  }
  int bipartite_matching() {
    int ret = 0;
    while (true) {
      bfs();
      vv.assign(graph.size(), false);
      int flow = 0;
      for (int i = 0; i < graph.size(); i++) {
        if (!used[i] && dfs(i)) ++flow;
      }
      if (flow == 0) return (ret);
      ret += flow;
    }
  }
  void output() {
    for (int i = 0; i < match.size(); i++) {
      if (~match[i]) {
        cout << match[i] << "-" << i << endl;
      }
    }
  }
};
using mi = modint;
int n, m;
void output(vector<vector<int>>& v) {
  for (ll i = 0; i < (int)n; i++) {
    for (ll j = 0; j < (int)m; j++) {
      if (j) cout << " ";
      cout << v[i][j];
    }
    cout << endl;
  }
}
vector<vector<int>> func1(const vector<vector<int>>& a) {
  vector<vector<int>> b(n, vector<int>(m, -1));
  for (ll i = 0; i < (int)n; i++) {
    HopcroftKarp hk(m, m);
    vector<int> rev(m, -1);
    for (ll j = 0; j < (int)n; j++) {
      vector<int> v;
      for (ll k = 0; k < (int)m; k++) {
        if (b[j][k] == -1) v.push_back(k);
      }
      for (ll k = 0; k < (int)m; k++) {
        if ((a[j][k] - 1) / m == i) {
          rev[(a[j][k] - 1) % m] = j;
          for (ll l = 0; l < (int)v.size(); l++) {
            hk.add_edge((a[j][k] - 1) % m, v[l]);
          }
        }
      }
    }
    hk.bipartite_matching();
    for (ll j = 0; j < (int)m; j++) {
      b[rev[j]][hk.match[j]] = i * m + j + 1;
    }
  }
  return b;
}
vector<vector<int>> func2(const vector<vector<int>>& b) {
  vector<vector<int>> c(n, vector<int>(m));
  for (ll i = 0; i < (int)m; i++) {
    for (ll j = 0; j < (int)n; j++) {
      c[(b[j][i] - 1) / m][i] = b[j][i];
    }
  }
  return c;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  vector<vector<int>> a(n, vector<int>(m));
  for (ll i = 0; i < (int)n; i++)
    for (ll j = 0; j < (int)m; j++) cin >> a[i][j];
  auto b = func1(a);
  output(b);
  auto c = func2(b);
  output(c);
  return 0;
}
