#include <bits/stdc++.h>
using namespace std;
map<int, vector<pair<pair<int, int>, int> > > all;
vector<int> tree[2][1000005];
int n, m;
void build(void) {
  int i;
  for (i = 0; i < n; i++) tree[0][i] = vector<int>(4 * (m + 5), 0);
  for (i = 0; i < m; i++) tree[1][i] = vector<int>(4 * (n + 5), 0);
}
void modify(int wh, int num, int pos, int val, int id, int l, int r) {
  if (r - l < 2) {
    tree[wh][num][id] = val;
    return;
  }
  int mid = (l + r) >> 1;
  if (pos < mid)
    modify(wh, num, pos, val, 2 * id, l, mid);
  else
    modify(wh, num, pos, val, 2 * id + 1, mid, r);
  tree[wh][num][id] = max(tree[wh][num][2 * id], tree[wh][num][2 * id + 1]);
}
int par[1000005];
int root(int v) { return par[v] < 0 ? v : (par[v] = root(par[v])); }
void union_set(int u, int v) {
  if ((u = root(u)) == (v = root(v))) return;
  if (par[u] > par[v]) swap(u, v);
  par[u] += par[v];
  par[v] = u;
}
void do_it(vector<pair<pair<int, int>, int> > &v) {
  vector<pair<int, int> > tmp;
  int i;
  for (i = 0; i < v.size(); i++)
    tmp.push_back(make_pair(v[i].first.first, v[i].second));
  sort(tmp.begin(), tmp.end());
  for (i = 1; i < tmp.size(); i++)
    if (tmp[i].first == tmp[i - 1].first)
      union_set(tmp[i].second, tmp[i - 1].second);
  tmp.clear();
  for (i = 0; i < v.size(); i++)
    tmp.push_back(make_pair(v[i].first.second, v[i].second));
  sort(tmp.begin(), tmp.end());
  for (i = 1; i < tmp.size(); i++)
    if (tmp[i].first == tmp[i - 1].first)
      union_set(tmp[i].second, tmp[i - 1].second);
}
int answer[1000005], rtval[1000005];
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  int i, j;
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      int x;
      scanf("%d", &x);
      all[x].push_back(make_pair(make_pair(i, j), i * m + j));
    }
  }
  build();
  memset(par, -1, sizeof(par));
  for (map<int, vector<pair<pair<int, int>, int> > >::iterator it = all.begin();
       it != all.end(); it++) {
    vector<pair<pair<int, int>, int> > &vec = (it->second);
    do_it(vec);
    for (i = 0; i < vec.size(); i++) {
      int x = vec[i].first.first, y = vec[i].first.second, ind = vec[i].second;
      ind = root(ind);
      rtval[ind] = max(rtval[ind], tree[0][x][1] + 1);
      rtval[ind] = max(rtval[ind], tree[1][y][1] + 1);
    }
    for (i = 0; i < vec.size(); i++) {
      int x = vec[i].first.first, y = vec[i].first.second, ind = vec[i].second;
      ind = root(ind);
      answer[x * m + y] = rtval[ind];
      modify(0, x, y, rtval[ind], 1, 0, m);
      modify(1, y, x, rtval[ind], 1, 0, n);
    }
  }
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) printf("%d ", answer[i * m + j]);
    printf("\n");
  }
  return 0;
}
