#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T& x) {
  char c;
  bool f = 0;
  while ((c = getchar()) < '0' || '9' < c) f |= (c == '-');
  for (x = (c ^ 48); '0' <= (c = getchar()) && c <= '9';
       x = (x << 1) + (x << 3) + (c ^ 48))
    ;
  if (f) x = -x;
}
template <class T>
inline T read(const T sample) {
  T x = 0;
  char c;
  bool f = 0;
  while ((c = getchar()) < '0' || '9' < c) f |= (c == '-');
  for (x = (c ^ 48); '0' <= (c = getchar()) && c <= '9';
       x = (x << 1) + (x << 3) + (c ^ 48))
    ;
  return f ? -x : x;
}
template <class T>
void fwrit(const T x) {
  if (x < 0) return (void)(putchar('-'), fwrit(-x));
  if (x > 9) fwrit(x / 10);
  putchar(x % 10 ^ 48);
}
template <class T>
inline T Max(const T x, const T y) {
  return x < y ? y : x;
}
template <class T>
inline T Min(const T x, const T y) {
  return x < y ? x : y;
}
template <class T>
inline T fab(const T x) {
  return x > 0 ? x : -x;
}
inline int gcd(const int a, const int b) { return b ? gcd(b, a % b) : a; }
inline void getInv(int inv[], const int lim, const int MOD) {
  inv[0] = inv[1] = 1;
  for (int i = 2; i <= lim; ++i)
    inv[i] = 1ll * inv[MOD % i] * (MOD - MOD / i) % MOD;
}
inline long long mulMod(const long long a, const long long b,
                        const long long mod) {
  return ((a * b - (long long)((long double)a / mod * b + 1e-8) * mod) % mod +
          mod) %
         mod;
}
const int maxn = 1e6;
const int maxm = maxn * 4;
struct edge {
  int to, nxt;
  edge(const int T = 0, const int N = 0) : to(T), nxt(N) {}
} e[maxm * 2 + 5];
int tail[maxn + 5], ecnt;
int in[maxn + 5];
inline void add_edge(const int u, const int v) {
  e[++ecnt] = edge(v, tail[u]);
  tail[u] = ecnt;
  ++in[v];
}
int fa[maxn + 5];
inline void build() {
  for (signed i = (1), i_end_ = (maxn); i <= i_end_; ++i) fa[i] = i;
}
int root(const int u) { return fa[u] == u ? u : fa[u] = root(fa[u]); }
struct Points {
  int w, x, y;
  Points(const int W = 0, const int X = 0, const int Y = 0)
      : w(W), x(X), y(Y) {}
  inline bool operator<(const Points rhs) const { return w < rhs.w; }
};
vector<Points> r[maxn + 5], c[maxn + 5];
int n, m;
inline void Init() {
  n = read(1), m = read(1);
  Points p = Points(0, 0, 0);
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i) r[i].push_back(p);
  for (signed i = (1), i_end_ = (m); i <= i_end_; ++i) c[i].push_back(p);
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i)
    for (signed j = (1), j_end_ = (m); j <= j_end_; ++j) {
      p = Points(read(1), i, j);
      r[i].push_back(p), c[j].push_back(p);
    }
}
inline int getid(const int x, const int y) { return (x - 1) * m + y; }
inline void Shrink() {
  build();
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i) {
    sort(r[i].begin(), r[i].end());
    for (signed j = (2), j_end_ = (m); j <= j_end_; ++j)
      if (r[i][j].w == r[i][j - 1].w)
        fa[root(getid(r[i][j].x, r[i][j].y))] =
            root(getid(r[i][j - 1].x, r[i][j - 1].y));
  }
  for (signed j = (1), j_end_ = (m); j <= j_end_; ++j) {
    sort(c[j].begin(), c[j].end());
    for (signed i = (2), i_end_ = (n); i <= i_end_; ++i)
      if (c[j][i].w == c[j][i - 1].w)
        fa[root(getid(c[j][i].x, c[j][i].y))] =
            root(getid(c[j][i - 1].x, c[j][i - 1].y));
  }
}
inline void Build() {
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i)
    for (signed j = (2), j_end_ = (m); j <= j_end_; ++j)
      if (r[i][j].w != r[i][j - 1].w)
        add_edge(root(getid(r[i][j - 1].x, r[i][j - 1].y)),
                 root(getid(r[i][j].x, r[i][j].y)));
  for (signed j = (1), j_end_ = (m); j <= j_end_; ++j)
    for (signed i = (2), i_end_ = (n); i <= i_end_; ++i)
      if (c[j][i].w != c[j][i - 1].w)
        add_edge(root(getid(c[j][i - 1].x, c[j][i - 1].y)),
                 root(getid(c[j][i].x, c[j][i].y)));
}
int dis[maxn + 5];
queue<int> Q;
inline void Topo() {
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i)
    for (signed j = (1), j_end_ = (m); j <= j_end_; ++j)
      if (root(getid(i, j)) == getid(i, j)) add_edge(0, getid(i, j));
  Q.push(0);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    for (signed i = tail[u], v = e[i].to; i; i = e[i].nxt, v = e[i].to)
      if (--in[v] == 0) {
        dis[v] = dis[u] + 1;
        Q.push(v);
      }
  }
}
inline void Writans() {
  for (signed i = (1), i_end_ = (n); i <= i_end_; ++i) {
    for (signed j = (1), j_end_ = (m); j <= j_end_; ++j)
      fwrit(dis[root(getid(i, j))]), putchar(' ');
    putchar('\n');
  }
}
signed main() {
  Init();
  Shrink();
  Build();
  Topo();
  Writans();
  return 0;
}
