#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> edges;
class DSU {
 private:
  int n;

 private:
  vector<int> parent, size;

 public:
  DSU(int v) {
    n = v;
    for (int i = 0; i < n; i++) {
      parent.push_back(i);
      size.push_back(1);
    }
  }

 public:
  int findRoot(int curr) {
    if (curr == parent[curr]) return curr;
    return parent[curr] = findRoot(parent[curr]);
  }

 public:
  bool unite(int a, int b) {
    int rootA = findRoot(a);
    int rootB = findRoot(b);
    if (rootA == rootB) return true;
    if (size[rootA] > size[rootB]) {
      parent[rootB] = rootA;
      size[rootA] += size[rootB];
    } else {
      parent[rootA] = rootB;
      size[rootB] += size[rootA];
    }
    return false;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, m;
  cin >> n >> m;
  edges.resize(n * m + 1);
  int in[n * m + 1];
  memset(in, 0, sizeof(in));
  map<pair<int, int>, int> mp;
  DSU dsu(n * m + 1);
  bool row[n * m + 1], col[n * m + 1];
  memset(row, 0, sizeof(row));
  memset(col, 0, sizeof(col));
  int tab[n + 1][m + 1];
  int val = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      cin >> tab[i][j];
      mp[{i, j}] = val++;
    }
  }
  for (int i = 1; i <= n; ++i) {
    vector<pair<int, int>> a;
    a.push_back({0, 0});
    for (int j = 1; j <= m; ++j) {
      a.push_back({tab[i][j], j});
    }
    sort(a.begin(), a.end());
    for (int j = 1; j <= m; ++j) {
      if (a[j].first == a[j - 1].first) {
        int u = mp[{i, a[j].second}];
        int v = mp[{i, a[j - 1].second}];
        dsu.unite(u, v);
      }
    }
  }
  for (int i = 1; i <= m; ++i) {
    vector<pair<int, int>> a;
    a.push_back({0, 0});
    for (int j = 1; j <= n; ++j) {
      a.push_back({tab[j][i], j});
    }
    sort(a.begin(), a.end());
    for (int j = 1; j <= n; ++j) {
      if (a[j].first == a[j - 1].first) {
        int u = mp[{a[j].second, i}];
        int v = mp[{a[j - 1].second, i}];
        dsu.unite(u, v);
      }
    }
  }
  int par[n * m + 1];
  for (int i = 1; i <= n * m; ++i) par[i] = dsu.findRoot(i);
  for (int i = 1; i <= n; ++i) {
    if (!row[i]) {
      row[i] = true;
      vector<pair<int, int>> a;
      a.push_back({0, 0});
      for (int k = 1; k <= m; ++k) {
        a.push_back({tab[i][k], k});
      }
      sort(a.begin(), a.end());
      for (int k = 2; k <= m; ++k) {
        int u = mp[{i, a[k - 1].second}];
        int v = mp[{i, a[k].second}];
        int pu = par[u];
        int pv = par[v];
        if (pu != pv) {
          edges[pv].push_back(pu);
          in[pu]++;
        }
      }
    }
  }
  for (int j = 1; j <= m; ++j) {
    if (!col[j]) {
      col[j] = true;
      vector<pair<int, int>> a;
      a.push_back({0, 0});
      for (int k = 1; k <= n; ++k) {
        a.push_back({tab[k][j], k});
      }
      sort(a.begin(), a.end());
      for (int k = 2; k <= n; ++k) {
        int u = mp[{a[k - 1].second, j}];
        int v = mp[{a[k].second, j}];
        int pu = par[u];
        int pv = par[v];
        if (pu != pv) {
          edges[pv].push_back(pu);
          in[pu]++;
        }
      }
    }
  }
  queue<int> q;
  for (int i = 1; i <= n * m; ++i)
    if (par[i] == i && in[i] == 0) q.push(i);
  vector<int> order;
  while (q.size() > 0) {
    int first = q.front();
    q.pop();
    order.push_back(first);
    for (auto node : edges[first]) {
      if (--in[node] == 0) q.push(node);
    }
  }
  int dp[n * m + 1];
  for (int i = order.size() - 1; i >= 0; --i) {
    int v = order[i];
    int ans = 1;
    for (auto node : edges[v]) {
      ans = max(ans, dp[node] + 1);
    }
    dp[v] = ans;
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      val = mp[{i, j}];
      int p = par[val];
      cout << dp[p] << " ";
    }
    cout << '\n';
  }
  return 0;
}
