#include <bits/stdc++.h>
using namespace std;
using vint = vector<long long>;
using vvint = vector<vint>;
using pint = pair<long long, long long>;
using vpint = vector<pint>;
template <typename T>
using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
constexpr long double pi = 3.1415926535897932384626433832795028;
constexpr long long dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
constexpr long long dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
long long gcd(long long a, long long b) {
  while (b) {
    swap(a %= b, b);
  }
  return a;
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &rhs) {
  os << "(" << rhs.first << ", " << rhs.second << ")";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &rhs) {
  os << "{";
  for (auto itr = rhs.begin(); itr != rhs.end(); itr++) {
    os << *itr << (next(itr) != rhs.end() ? ", " : "");
  }
  os << "}";
  return os;
}
struct Setup {
  static constexpr long long PREC = 20;
  Setup() {
    cout << fixed << setprecision(PREC);
    cerr << fixed << setprecision(PREC);
  };
} setup;
template <typename T>
struct Dinic {
  struct edge {
    long long to, rev;
    T cap;
    bool isRev;
  };
  long long n;
  T ZERO, INF;
  std::vector<std::vector<edge>> G;
  std::vector<long long> level, iter;
  Dinic(long long n, T INF = std::numeric_limits<T>::max(), T ZERO = T())
      : n(n), INF(INF), ZERO(ZERO), G(n), level(n), iter(n) {}
  void addEdge(long long from, long long to, T cap) {
    G[from].push_back({to, (long long)G[to].size(), cap, false});
    G[to].push_back({from, (long long)G[from].size() - 1, ZERO, true});
  }
  void bfs(long long s) {
    fill(level.begin(), level.end(), -1);
    std::queue<long long> que;
    level[s] = 0;
    que.push(s);
    while (!que.empty()) {
      long long v = que.front();
      que.pop();
      for (long long i = 0; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > ZERO && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.push(e.to);
        }
      }
    }
  }
  T dfs(long long v, long long t, T f) {
    if (v == t) {
      return f;
    }
    for (long long &i = iter[v]; i < G[v].size(); i++) {
      edge &e = G[v][i];
      if (level[v] < level[e.to] && e.cap > ZERO) {
        T d = dfs(e.to, t, std::min(f, e.cap));
        if (d > ZERO) {
          e.cap -= d;
          G[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return ZERO;
  }
  T calcMaxFlow(long long s, long long t, T lim) {
    T flow = ZERO;
    while (true) {
      bfs(s);
      if (level[t] < 0 || lim == ZERO) {
        return flow;
      }
      fill(iter.begin(), iter.end(), 0);
      T f;
      while ((f = dfs(s, t, lim)) > ZERO) {
        flow += f;
        lim -= f;
      }
    }
  }
  T calcMaxFlow(long long s, long long t) { return calcMaxFlow(s, t, INF); }
  std::map<std::pair<long long, long long>, T> &getMaxFlow() {
    std::map<std::pair<long long, long long>, T> ret;
    for (long long i = 0; i < n; i++) {
      for (long long j = 0; j < G[i].size(); j++) {
        edge &e = G[i][j];
        if (e.isRev) {
          ret[{e.to, i}] = e.cap;
        }
      }
    }
    return ret;
  }
  std::map<std::pair<long long, long long>, T> &getMinCut(long long s) {
    std::map<std::pair<long long, long long>, T> ret;
    std::vector<long long> visited(n);
    std::queue<long long> que;
    que.push(s);
    while (!que.empty()) {
      long long v = que.front();
      que.pop();
      if (visited[v]) {
        continue;
      }
      visited[v] = true;
      for (long long i = 0; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > ZERO) {
          que.push(e.to);
        }
      }
    }
    for (long long i = 0; i < n; i++) {
      if (visited[i]) {
        continue;
      }
      for (long long j = 0; j < G[i].size(); j++) {
        edge &e = G[i][j];
        if (e.isRev && visited[e.to]) {
          ret[{e.to, i}] = e.cap;
        }
      }
    }
    return ret;
  }
};
long long N, M;
long long A[110][110];
signed main() {
  cin >> N >> M;
  for (long long i = 0; i < (N); i++)
    for (long long j = 0; j < (M); j++) {
      cin >> A[i][j];
      A[i][j]--;
    }
  for (long long i = 0; i < (M); i++) {
    Dinic<long long> dnc(N + N + 2);
    long long s = N + N, t = N + N + 1;
    vvint alc(N, vint(N, -1));
    for (long long j = 0; j < (N); j++) {
      dnc.addEdge(s, j, 1);
      dnc.addEdge(j + N, t, 1);
    }
    for (long long j = 0; j < (N); j++) {
      for (long long k = i; k < M; k++) {
        long long c = A[j][k] / M;
        if (alc[j][c] < 0) {
          alc[j][c] = k;
          dnc.addEdge(j, c + N, 1);
        }
      }
    }
    dnc.calcMaxFlow(s, t);
    auto flow = dnc.getMaxFlow();
    vpint m;
    for (auto p : flow) {
      if (p.first.first != s && p.first.second != t && p.second != 0) {
        m.push_back(p.first);
      }
    }
    for (long long j = 0; j < (N); j++) {
      swap(A[m[j].first][i], A[m[j].first][alc[m[j].first][m[j].second - N]]);
    }
  }
  for (long long i = 0; i < (N); i++) {
    for (long long j = 0; j < (M); j++) {
      cout << A[i][j] + 1 << " ";
    }
    cout << endl;
  }
  for (long long i = 0; i < (M); i++) {
    for (long long j = 0; j < (N); j++) {
      for (long long k = j + 1; k < N; k++) {
        if (A[j][i] > A[k][i]) {
          swap(A[j][i], A[k][i]);
        }
      }
    }
  }
  for (long long i = 0; i < (N); i++) {
    for (long long j = 0; j < (M); j++) {
      cout << A[i][j] + 1 << " ";
    }
    cout << endl;
  }
}
