#include <bits/stdc++.h>
using namespace std;
struct Data {
  int r, c, v;
  bool operator<(const Data &r) const { return v < r.v; }
};
vector<vector<int> > mat, ans;
Data sorteds[1001000];
int mR[1001000], mC[1001000];
map<pair<int, int>, vector<int> > mr, mc;
void recursiveFix(int rr, int cc) {
  vector<int> &vv = mr[pair<int, int>(rr, mat[rr][cc])];
  vector<int> t = vv;
  for (int j = int(0); j < int(vv.size()); j++) {
    ans[rr][vv[j]] = ans[rr][cc];
  }
  vv.clear();
  vector<int> &vv2 = mc[pair<int, int>(cc, mat[rr][cc])];
  vector<int> t2 = vv2;
  for (int j = int(0); j < int(vv2.size()); j++) {
    ans[vv2[j]][cc] = ans[rr][cc];
  }
  vv2.clear();
  for (int j = int(0); j < int(t2.size()); j++) recursiveFix(t2[j], cc);
  for (int j = int(0); j < int(t.size()); j++) recursiveFix(rr, t[j]);
}
int main() {
  int N, M;
  while (scanf("%d %d", &N, &M) != EOF) {
    int c = 0;
    vector<int> t(M + 1);
    mr.clear(), mc.clear();
    mat.clear();
    ans.clear();
    mat.push_back(t);
    ans.push_back(t);
    for (int i = int(1); i < int(N + 1); i++) {
      mat.push_back(t);
      ans.push_back(t);
      for (int j = int(1); j < int(M + 1); j++) {
        scanf("%d", &mat[i][j]);
        sorteds[c++] = Data{i, j, mat[i][j]};
        ans[i][j] = 1;
        mr[pair<int, int>(i, mat[i][j])].push_back(j);
        mc[pair<int, int>(j, mat[i][j])].push_back(i);
      }
    }
    sort(sorteds, sorteds + c);
    memset(mR, 0, sizeof(mR));
    memset(mC, 0, sizeof(mC));
    int prev = -1;
    priority_queue<Data> q;
    for (int i = int(0); i < int(c); i++) {
      if (prev != sorteds[i].v) {
        while (!q.empty()) {
          int rr = q.top().r, cc = q.top().c;
          recursiveFix(rr, cc);
          q.pop();
        }
      }
      int r = sorteds[i].r, c = sorteds[i].c;
      ans[r][c] = 0;
      if (mat[r][mR[r]] == mat[r][c])
        ans[r][c] = max(ans[r][c], ans[r][mR[r]]);
      else
        ans[r][c] = max(ans[r][c], ans[r][mR[r]] + 1);
      if (mat[mC[c]][c] == mat[r][c])
        ans[r][c] = max(ans[r][c], ans[mC[c]][c]);
      else
        ans[r][c] = max(ans[r][c], ans[mC[c]][c] + 1);
      q.push(Data{r, c, ans[r][c]});
      mR[r] = c;
      mC[c] = r;
      prev = sorteds[i].v;
    }
    while (!q.empty()) {
      int rr = q.top().r, cc = q.top().c;
      recursiveFix(rr, cc);
      q.pop();
    }
    for (int i = int(0); i < int(N); i++) {
      for (int j = int(0); j < int(M); j++)
        printf("%d%c", ans[i + 1][j + 1], " \n"[j == M - 1]);
    }
  }
  return 0;
}
