#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];       }     }   }