#include <bits/stdc++.h>
using namespace std;
const int M = 1010, mod = 1000000007;
vector<vector<int> > lst[M];
vector<vector<int> > flag[M];
vector<int> sz[M];
vector<int> tmp, bmp;
vector<pair<int, int> > edge;
int id[M][M];
int pos[M][M];
int visited[M];
string s, t;
void make_list(int u, string &a) {
  int i = 0, j = 0;
  char d[10];
  tmp.clear();
  a += ',';
  while (a[i] != ':') i++;
  i++;
  while (i < a.size()) {
    if (a[i] == ',') {
      d[j++] = '\0';
      if (atoi(d) > 0) tmp.push_back(atoi(d));
      j = 0;
    } else
      d[j++] = a[i];
    i++;
  }
  bmp.resize(tmp.size());
  for (i = 0; i < tmp.size(); i++) {
    int v = tmp[i];
    id[v][u] = lst[u].size();
    pos[v][u] = i;
  }
  lst[u].push_back(tmp);
  flag[u].push_back(bmp);
  sz[u].push_back(tmp.size());
}
void dec(int u, int v) {
  for (int i = 0; i < lst[u].size(); i++) {
    for (int j = 0; j < lst[u][i].size(); j++) {
      if (lst[u][i][j] == v) {
        sz[u][i]--;
        flag[u][i][j] = 1;
        return;
      }
    }
  }
}
bool isinsane(int u) {
  int i, j, k, cnt = 0;
  for (i = 0; i < lst[u].size(); i++) cnt += (sz[u][i] > 0);
  return cnt != 1;
}
pair<int, int> find_leaf(int n) {
  int i, j, k;
  vector<int> r;
  for (i = 1; i <= n; i++) r.push_back(i);
  random_shuffle((r).begin(), (r).end());
  for (int first = 0; first < r.size(); first++) {
    i = r[first];
    if (visited[i]) continue;
    for (j = 0; j < lst[i].size(); j++) {
      if (sz[i][j] == 1) {
        for (k = 0; k < flag[i][j].size(); k++) {
          if (flag[i][j][k] == 0) return make_pair(i, lst[i][j][k]);
        }
      }
    }
  }
  return make_pair(-1, -1);
}
int main() {
  ios_base::sync_with_stdio(false);
  int n, i, j, k;
  srand(time(NULL));
  memset((id), (-1), sizeof(id));
  cin >> n;
  for (j = 1; j <= n; j++) {
    cin >> s;
    s += '-';
    for (i = 0; i < s.size(); i++) {
      if (s[i] == '-') {
        make_list(j, t);
        t.clear();
      } else
        t += s[i];
    }
  }
  while (true) {
    pair<int, int> g = find_leaf(n);
    if (g.first == -1) break;
    edge.push_back(g);
    int u = g.second, v = g.first;
    visited[u] = 1;
    if (isinsane(u)) {
      printf("%d\n", -1);
      return 0;
    }
    for (i = 1; i <= n; i++) {
      if (visited[i]) continue;
      int l = id[u][i], r = id[v][i], p = pos[u][i];
      if (l == -1) continue;
      if (i != v && l != r) {
        printf("%d\n", -1);
        return 0;
      }
      flag[i][l][p] = 1;
      sz[i][l]--;
    }
    dec(u, g.first);
  }
  if (edge.size() != n - 1)
    printf("%d\n", -1);
  else {
    printf("%d\n", edge.size());
    for (pair<int, int> e : edge) printf("%d %d\n", e.first, e.second);
  }
  return 0;
}
