#include <bits/stdc++.h>
using namespace std;
vector<long long> edges[1000100];
long long newBoard[1000100];
long long board[1000100];
set<pair<int, int> > nodes;
long long maxParent[1000100];
bool seen[1000100];
long long n, m;
bool sortbyfst(const pair<long long, long long> &a,
               const pair<long long, long long> &b) {
  return (a.first < b.first);
}
bool sortbyval(long long a, long long b) { return (board[a] < board[b]); }
long long parent[1000100];
long long subtree_size[1000100];
void init(long long n) {
  for (long long i = 0; i < n; i++) {
    parent[i] = i;
    subtree_size[i] = 1;
  }
}
long long root(long long x) {
  return parent[x] == x ? x : parent[x] = root(parent[x]);
}
void join(long long x, long long y) {
  x = root(x);
  y = root(y);
  if (x == y) return;
  if (subtree_size[x] < subtree_size[y]) {
    parent[x] = y;
    subtree_size[y] += subtree_size[x];
    edges[y].insert(edges[y].end(), edges[x].begin(), edges[x].end());
  } else {
    parent[y] = x;
    subtree_size[x] += subtree_size[y];
    edges[x].insert(edges[x].end(), edges[y].begin(), edges[y].end());
  }
}
void add(long long u, long long v) {
  if (board[u] == board[v]) {
    join(u, v);
    return;
  }
  edges[root(u)].push_back(root(v));
  return;
}
void findVals() {
  for (set<pair<int, int> >::iterator it = nodes.begin(); it != nodes.end();
       ++it) {
    pair<int, int> data = *it;
    int u = root(data.second);
    if (u != data.second) continue;
    long long newVal = maxParent[u] + 1;
    newBoard[u] = newVal;
    for (vector<long long>::iterator it = edges[u].begin();
         it != edges[u].end(); ++it) {
      long long v = *it;
      maxParent[root(v)] = max((int)maxParent[root(v)], (int)newVal);
    }
  }
}
int main() {
  cin >> n >> m;
  long long min = 1000000005;
  long long minLoc;
  vector<pair<long long, long long> > cols[m + 1];
  vector<pair<long long, long long> > rows[n + 1];
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < m; j++) {
      long long data;
      cin >> data;
      long long loc = (i * m) + j + 1;
      board[loc] = data;
      rows[i].push_back(make_pair(data, loc));
      cols[j].push_back(make_pair(data, loc));
      nodes.insert(make_pair(data, loc));
      if (data < min) {
        min = data;
        minLoc = loc;
      }
    }
  }
  init(1000100);
  for (long long i = 0; i < n; i++) {
    sort(rows[i].begin(), rows[i].end(), sortbyfst);
    for (long long j = 0; j < m - 1; j++) {
      add(rows[i][j].second, rows[i][j + 1].second);
    }
  }
  for (long long i = 0; i < m; i++) {
    sort(cols[i].begin(), cols[i].end(), sortbyfst);
    for (long long j = 0; j < n - 1; j++) {
      add(cols[i][j].second, cols[i][j + 1].second);
    }
  }
  maxParent[minLoc] = 0;
  findVals();
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < m; j++) {
      printf("%lld ", newBoard[root((i * m) + j + 1)]);
    }
    printf("\n");
  }
}
