#include <bits/stdc++.h>
using namespace std;
int n, m;
struct node {
  int num;
  int x, y, id;
  node() {}
  node(int nnum, int i) {
    num = nnum;
    x = i / m;
    y = i % m;
    id = i;
  }
  friend bool operator<(node a, node b) { return a.num < b.num; }
} a[1111111];
int mh[1111111], b[1111111], ml[1111111], ans[1111111], t = 0, xh[1111111],
                                                        xl[1111111];
struct bcj {
  int fa[1111111];
  void init(int n) {
    for (int i = 0; i < n; i++) fa[i] = i;
  }
  int root(int x) {
    while (x != fa[x]) x = fa[x] = fa[fa[x]];
    return x;
  }
  void unite(int x, int y) { fa[root(x)] = root(y); }
} se;
int main() {
  cin >> n >> m;
  for (int i = 0; i < n * m; i++) {
    int x;
    scanf("%d", &x);
    a[i] = (node(x, i));
  }
  se.init(n * m);
  a[n * m] = (node(0x3f3f3f3f, 0));
  sort(a, a + n * m + 1);
  int l = 0, r = 0;
  for (int j = 0; j < n * m + 1; j++) {
    if (j - l == 0 || a[j].num == a[l].num)
      ;
    else {
      r = j;
      for (int i = l; i < r; i++) {
        if (!xh[a[i].x])
          xh[a[i].x] = i;
        else
          se.unite(xh[a[i].x], i);
        if (!xl[a[i].y])
          xl[a[i].y] = i;
        else
          se.unite(xl[a[i].y], i);
      }
      for (int i = l; i < r; i++)
        ans[se.root(i)] = max(ans[se.root(i)], max(mh[a[i].x], ml[a[i].y]) + 1);
      for (int i = l; i < r; i++)
        b[a[i].id] = mh[a[i].x] = ml[a[i].y] = ans[se.root(i)],
        xh[a[i].x] = xl[a[i].y] = 0;
      l = j;
    }
  }
  for (int i = 0; i < n * m; i++) {
    printf("%d%c", b[i], i % m == m - 1 ? '\n' : ' ');
  }
  return 0;
}
