#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 30000, MAX_K = 200;
int n, k;
int d[MAX_K][MAX_N], pick[MAX_K];
int best_height[MAX_N];
pair<int, int> best_path[MAX_N];
vector<int> from_root[MAX_N];
vector<int> arcs[MAX_N];
vector<pair<int, int> > edges;
vector<int> path_by_pair[MAX_K][MAX_K];
pair<int, int> make_edge(int u, int v) {
  if (v < u) {
    swap(u, v);
  }
  return {u, v};
}
void process_by_pair(int ui, int vi) {
  int dist = d[ui][pick[vi]];
  vector<int> path(dist + 1, -1);
  for (int i = 0; i < n; i++) {
    int du = d[ui][i], dv = d[vi][i];
    if (du + dv < dist || (du + dv - dist) % 2 == 1) {
      throw 1;
    }
    int h = (du + dv - dist) / 2;
    int pos = du - h;
    if (h == 0) {
      path[pos] = i;
    }
    if (h < best_height[i]) {
      best_height[i] = h;
      best_path[i] = {ui, vi};
    }
  }
  for (int i = 0; i < dist; i++) {
    edges.push_back(make_edge(path[i], path[i + 1]));
  }
  for (auto c : path) {
    if (c == -1) {
      throw 1;
    }
  }
  path_by_pair[ui][vi] = path;
}
void add_to_roots() {
  vector<pair<int, int> > by_h;
  for (int i = 0; i < n; i++) {
    by_h.push_back({best_height[i], i});
  }
  sort(by_h.begin(), by_h.end());
  for (auto cur_pair : by_h) {
    int h = cur_pair.first, v = cur_pair.second;
    int pl = best_path[v].first, pr = best_path[v].second;
    int root = path_by_pair[pl][pr][d[pl][v] - h];
    if (h > 0) {
      if ((int)from_root[root].size() < h) {
        throw 1;
      }
      edges.push_back(make_edge(from_root[root][h - 1], v));
    }
    if ((int)from_root[root].size() == h) {
      from_root[root].push_back(v);
    }
  }
}
void verify_distances(int vi) {
  int v = pick[vi];
  vector<int> dist(n, -1);
  vector<int> front(1, v);
  dist[v] = 0;
  for (int fi = 0; fi < (int)front.size(); fi++) {
    int cur = front[fi];
    for (auto next : arcs[cur])
      if (dist[next] == -1) {
        dist[next] = dist[cur] + 1;
        front.push_back(next);
      }
  }
  for (int i = 0; i < n; i++) {
    if (d[vi][i] != dist[i]) {
      throw 1;
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  fill(best_height, best_height + MAX_N, 1000000000);
  fill(pick, pick + MAX_K, -1);
  try {
    cin >> n >> k;
    for (int i = 0; i < k; i++) {
      for (int j = 0; j < n; j++) {
        cin >> d[i][j];
        if (d[i][j] == 0) {
          pick[i] = j;
        }
      }
      if (pick[i] == -1) {
        throw 1;
      }
    }
    for (int i = 0; i < k; i++) {
      process_by_pair(0, i);
    }
    add_to_roots();
    sort(edges.begin(), edges.end());
    edges.resize(unique(edges.begin(), edges.end()) - edges.begin());
    for (auto edge : edges) {
      int u = edge.first, v = edge.second;
      arcs[u].push_back(v);
      arcs[v].push_back(u);
    }
    for (int i = 0; i < k; i++) {
      verify_distances(i);
    }
    for (auto edge : edges) {
      cout << edge.first + 1 << ' ' << edge.second + 1 << '\n';
    }
  } catch (int a) {
    cout << "-1\n";
  }
  return 0;
}
