#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll llinf = (1ll << 61) - 1;
const double eps = 1e-6, ldeps = 1e-9;
struct Dbg {
  static constexpr auto &os = cout;
  template <class C>
  static auto dud(C *x) -> decltype(os << *x, 0);
  template <class C>
  static char dud(...);
  template <class C>
  typename enable_if<sizeof dud<C>(0) != 1, Dbg &>::type operator<<(
      const C &x) {
    os << x;
    return *this;
  }
  template <class C>
  Dbg &dump(C b, C e) {
    *this << "\n[";
    int cur = 0;
    for (C i = b; i != e and cur < 26; i++, cur++)
      *this << ", " + 2 * (i == b) << *i;
    return *this << ']';
  }
  template <class C>
  typename enable_if<sizeof dud<C>(0) == 1, Dbg &>::type operator<<(
      const C &x) {
    return dump(begin(x), end(x));
  }
  template <class C, size_t X>
  typename enable_if<sizeof(C) != 1, Dbg &>::type operator<<(C (&x)[X]) {
    return dump(begin(x), end(x));
  }
  template <class B, class C>
  Dbg &operator<<(const pair<B, C> &x) {
    return *this << '{' << x.first << ", " << x.second << '}';
  }
  template <class C, size_t Y>
  struct TP {
    void operator()(Dbg &os, const C &t) {
      TP<C, Y - 1>()(os, t);
      os << ", " << get<Y - 1>(t);
    }
  };
  template <class C>
  struct TP<C, 1> {
    void operator()(Dbg &os, const C &t) { os << get<0>(t); }
  };
  template <class... C>
  Dbg &operator<<(const tuple<C...> &t) {
    os << '{', TP<decltype(t), sizeof...(C)>()(*this, t);
    return *this << '}';
  }
  Dbg &operator<<(ostream &(*x)(std::ostream &)) {
    os << x;
    return *this;
  }
} dbg;
void err(istringstream *iss) { delete iss; }
template <class C, class... Args>
void err(istringstream *iss, const C &val, const Args &...args) {
  string name;
  *iss >> name;
  if (name.back() == ',') name.pop_back();
  dbg << name << " = " << val << "; ", err(iss, args...);
}
int n, m, K, T, Q, cn;
const int inf = 1000000007, mxnm = 1000005;
vector<vector<int> > a;
vector<pair<int, int> > pos[mxnm];
int maxrow[mxnm], maxcol[mxnm];
template <class C>
C compress(vector<C> &v) {
  int sz = int(v.size());
  vector<pair<C, int> > tmp(sz);
  for (int i = 0; i < sz; i++) {
    tmp[i] = {v[i], i};
  }
  sort(begin(tmp), end(tmp));
  int cur = 1;
  for (int i = 0; i < sz; i++) {
    cur += i and tmp[i].first != tmp[i - 1].first;
    v[tmp[i].second] = cur;
  }
  return cur;
}
int os[mxnm], lastrow[mxnm], lastcol[mxnm];
class DSU {
  vector<int> dsupar, siz;

 public:
  int cntDSU;
  void reset() {
    int sz = int(dsupar.size());
    for (int i = 0; i < sz; i++) dsupar[i] = i, siz[i] = 1;
  }
  DSU(int N, int noOfSets = -1) {
    dsupar.resize(N + 5), siz.resize(N + 5);
    reset();
    cntDSU = noOfSets == -1 ? N : noOfSets;
  }
  int find(int x) { return dsupar[x] == x ? x : dsupar[x] = find(dsupar[x]); }
  void union_(int u, int v) {
    if ((u = find(u)) == (v = find(v))) return;
    if (siz[u] < siz[v]) swap(u, v);
    dsupar[v] = u, siz[u] += siz[v], siz[v] = 0, os[u] = max(os[u], os[v]);
    cntDSU--;
  }
} dsu(mxnm);
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(NULL);
  cout.precision(11);
  cin >> n >> m;
  a.resize(n + 5, vector<int>(m + 5));
  vector<int> a2(n * m);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a2[i * m + j];
    }
  }
  int o = compress(a2);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      pos[a2[i * m + j]].push_back({i, j});
      a[i][j] = a2[i * m + j];
    }
  }
  memset(lastrow, -1, sizeof(lastrow)), memset(lastcol, -1, sizeof(lastcol));
  for (int i = 1; i <= o; i++) {
    for (auto &j : pos[i]) {
      os[j.first * m + j.second] = max(maxrow[j.first], maxcol[j.second]) + 1;
    }
    for (auto &j : pos[i]) {
      if (lastrow[j.first] == -1)
        lastrow[j.first] = j.second;
      else
        dsu.union_(j.first * m + j.second, j.first * m + lastrow[j.first]);
      if (lastcol[j.second] == -1)
        lastcol[j.second] = j.first;
      else
        dsu.union_(j.first * m + j.second, lastcol[j.second] * m + j.second);
    }
    for (auto &j : pos[i]) {
      a[j.first][j.second] = os[dsu.find(j.first * m + j.second)];
      lastrow[j.first] = lastcol[j.second] = -1;
    }
    for (auto &j : pos[i]) {
      maxrow[j.first] = max(maxrow[j.first], a[j.first][j.second]),
      maxcol[j.second] = max(maxcol[j.second], a[j.first][j.second]);
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cout << a[i][j] << " \n"[j == m - 1];
    }
  }
}
