#include <bits/stdc++.h>
void dfs_mark(int32_t vertex, std::vector<int32_t>* graph, bool* visited,
              int32_t mark, int32_t* marks) {
  marks[vertex] = mark;
  visited[vertex] = true;
  for (int32_t i = 0; i < graph[vertex].size(); i++)
    if (!visited[graph[vertex][i]])
      dfs_mark(graph[vertex][i], graph, visited, mark, marks);
}
void dfs_topsort(int32_t vertex, std::vector<int32_t>* graph, bool* perm,
                 int32_t* answer) {
  for (int32_t i = 0; i < graph[vertex].size(); i++)
    if (!perm[graph[vertex][i]])
      dfs_topsort(graph[vertex][i], graph, perm, answer);
  perm[vertex] = true;
  answer[vertex] = 0;
  for (int32_t i = 0; i < graph[vertex].size(); i++)
    answer[vertex] = std::min(answer[vertex], answer[graph[vertex][i]] - 1);
}
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  std::cout.tie(0);
  int32_t n, m;
  std::cin >> n >> m;
  int32_t** table = new int32_t*[n];
  for (int32_t i = 0; i < n; i++) {
    table[i] = new int32_t[m];
    for (int32_t j = 0; j < m; j++) std::cin >> table[i][j];
  }
  std::vector<int32_t>* equal_edges = new std::vector<int32_t>[n * m];
  for (int32_t i = 0; i < n; i++) {
    std::map<int32_t, std::vector<int32_t> > equal;
    for (int32_t j = 0; j < m; j++) equal[table[i][j]].push_back(j);
    for (auto it = equal.begin(); it != equal.end(); it++) {
      for (int32_t j = 0; j < it->second.size() - 1; j++) {
        equal_edges[i * m + it->second[j]].push_back(i * m + it->second[j + 1]);
        equal_edges[i * m + it->second[j + 1]].push_back(i * m + it->second[j]);
      }
    }
  }
  for (int32_t i = 0; i < m; i++) {
    std::map<int32_t, std::vector<int32_t> > equal;
    for (int32_t j = 0; j < n; j++) equal[table[j][i]].push_back(j);
    for (auto it = equal.begin(); it != equal.end(); it++) {
      for (int32_t j = 0; j < it->second.size() - 1; j++) {
        equal_edges[it->second[j] * m + i].push_back(it->second[j + 1] * m + i);
        equal_edges[it->second[j + 1] * m + i].push_back(it->second[j] * m + i);
      }
    }
  }
  int32_t* vertex_indices = new int32_t[n * m];
  bool* visited = new bool[n * m];
  for (int32_t i = 0; i < n * m; i++) visited[i] = false;
  int32_t num_vertices = 0;
  for (int32_t i = 0; i < n; i++) {
    for (int32_t j = 0; j < m; j++) {
      if (visited[i * m + j]) continue;
      dfs_mark(i * m + j, equal_edges, visited, num_vertices, vertex_indices);
      num_vertices++;
    }
  }
  std::vector<int32_t>* greater_edges = new std::vector<int32_t>[num_vertices];
  std::vector<std::pair<int32_t, int32_t> > greater_edges_list;
  bool* source = new bool[num_vertices];
  for (int32_t i = 0; i < num_vertices; i++) source[i] = true;
  for (int32_t i = 0; i < n; i++) {
    std::map<int32_t, std::vector<int32_t> > equal;
    for (int32_t j = 0; j < m; j++) equal[table[i][j]].push_back(j);
    auto it2 = equal.begin();
    it2++;
    for (auto it = equal.begin(); it2 != equal.end(); it++, it2++) {
      greater_edges[vertex_indices[i * m + it->second[0]]].push_back(
          vertex_indices[i * m + it2->second[0]]);
      greater_edges_list.emplace_back(vertex_indices[i * m + it->second[0]],
                                      vertex_indices[i * m + it2->second[0]]);
      source[vertex_indices[i * m + it2->second[0]]] = false;
    }
  }
  for (int32_t i = 0; i < m; i++) {
    std::map<int32_t, std::vector<int32_t> > equal;
    for (int32_t j = 0; j < n; j++) equal[table[j][i]].push_back(j);
    auto it2 = equal.begin();
    it2++;
    for (auto it = equal.begin(); it2 != equal.end(); it++, it2++) {
      greater_edges[vertex_indices[it->second[0] * m + i]].push_back(
          vertex_indices[it2->second[0] * m + i]);
      greater_edges_list.emplace_back(vertex_indices[it->second[0] * m + i],
                                      vertex_indices[it2->second[0] * m + i]);
      source[vertex_indices[it2->second[0] * m + i]] = false;
    }
  }
  for (int32_t i = 0; i < num_vertices; i++) {
    std::sort(greater_edges[i].begin(), greater_edges[i].end());
    greater_edges[i].resize(
        std::unique(greater_edges[i].begin(), greater_edges[i].end()) -
        greater_edges[i].begin());
  }
  std::sort(greater_edges_list.begin(), greater_edges_list.end());
  greater_edges_list.resize(
      std::unique(greater_edges_list.begin(), greater_edges_list.end()) -
      greater_edges_list.begin());
  for (int32_t i = 0; i < num_vertices; i++) visited[i] = false;
  int32_t* ans_per_vertex = new int32_t[num_vertices];
  for (int32_t i = 0; i < num_vertices; i++)
    if (!visited[i]) dfs_topsort(i, greater_edges, visited, ans_per_vertex);
  int32_t min = 0;
  for (int32_t i = 0; i < num_vertices; i++)
    min = std::min(min, ans_per_vertex[i]);
  for (int32_t i = 0; i < n; i++) {
    for (int32_t j = 0; j < m; j++)
      std::cout << ans_per_vertex[vertex_indices[i * m + j]] - min + 1 << " ";
    std::cout << "\n";
  }
  return 0;
}
