#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int NM = 1001000;
ll a[NM];
vector<int> edges[NM];
vector<int> dag_edges[NM];
const int MAX_VERTICES = 1001000;
int dfs_index[MAX_VERTICES];
int lowlink[MAX_VERTICES];
stack<int> s;
bool in_stack[MAX_VERTICES];
int scc_counter;
int which_scc[MAX_VERTICES];
void connect(int v) {
  static int i = 1;
  lowlink[v] = dfs_index[v] = i++;
  s.push(v);
  in_stack[v] = true;
  for (auto w : edges[v]) {
    if (!dfs_index[w]) {
      connect(w);
      lowlink[v] = min(lowlink[v], lowlink[w]);
    } else if (in_stack[w]) {
      lowlink[v] = min(lowlink[v], dfs_index[w]);
    }
  }
  if (lowlink[v] == dfs_index[v]) {
    ++scc_counter;
    int w;
    do {
      w = s.top();
      s.pop();
      in_stack[w] = false;
      which_scc[w] = scc_counter;
    } while (w != v);
  }
}
void find_sccs(int n) {
  for (int v = 0; v < n; ++v)
    if (!dfs_index[v]) connect(v);
}
bool seen[NM];
void dfs(int u, vector<int>& postorder) {
  if (seen[u]) return;
  seen[u] = true;
  for (int v : dag_edges[u]) dfs(v, postorder);
  postorder.push_back(u);
}
vector<int> topsort() {
  vector<int> res;
  for (int i = 1; i <= scc_counter; i++) dfs(i, res);
  reverse(res.begin(), res.end());
  return res;
}
int compressed[NM];
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n * m; i++) cin >> a[i];
  for (int i = 0; i < n; i++) {
    vector<pair<ll, int>> row;
    for (int j = 0; j < m; j++) row.emplace_back(a[(m * i + j)], (m * i + j));
    sort(row.begin(), row.end());
    for (int j = 0; j < m - 1; j++) {
      edges[row[j].second].push_back(row[j + 1].second);
      if (row[j].first == row[j + 1].first)
        edges[row[j + 1].second].push_back(row[j].second);
    }
  }
  for (int i = 0; i < m; i++) {
    vector<pair<ll, int>> col;
    for (int j = 0; j < n; j++) col.emplace_back(a[(m * j + i)], (m * j + i));
    sort(col.begin(), col.end());
    for (int j = 0; j < n - 1; j++) {
      edges[col[j].second].push_back(col[j + 1].second);
      if (col[j].first == col[j + 1].first)
        edges[col[j + 1].second].push_back(col[j].second);
    }
  }
  find_sccs(n * m);
  for (int i = 0; i < n * m; i++) {
    for (int v : edges[i]) {
      if (which_scc[i] != which_scc[v])
        dag_edges[which_scc[i]].push_back(which_scc[v]);
    }
  }
  vector<int> topsorted = topsort();
  fill_n(compressed, NM, 1);
  compressed[topsorted[0]] = 1;
  for (int u : topsorted) {
    for (int v : dag_edges[u]) {
      compressed[v] = max(compressed[v], compressed[u] + 1);
    }
  }
  for (int i = 0; i < n * m; i++) {
    if (i != 0 && i % m == 0) cout << '\n';
    printf("%d ", compressed[which_scc[i]]);
  }
  cout << '\n';
  return 0;
}
