#include <bits/stdc++.h>
using namespace std;
const int inf = 2000000000;
const int N = 1e3 + 5;
int col[N], NumOfSubsets[N];
vector<int> a[N];
vector<vector<int>> b[N];
vector<int> get(string s) {
  int p = s.find(':');
  vector<int> f;
  int m = s.length(), val = 0;
  for (int j = p + 1; j <= m; j++) {
    if (j == m || s[j] == ',') {
      f.push_back(val);
      val = 0;
    } else {
      val = val * 10 + (s[j] - '0');
    }
  }
  return f;
}
vector<pair<int, int>> g[N];
void parse(int v, string s) {
  int m = s.length();
  vector<string> subset;
  string cur;
  for (int j = 0; j <= m; j++) {
    if (j == m || s[j] == '-') {
      subset.push_back(cur);
      cur = "";
    } else {
      cur += s[j];
    }
  }
  NumOfSubsets[v] = subset.size();
  a[v].resize(subset.size());
  b[v].resize(subset.size());
  for (int i = 0; i < subset.size(); i++) {
    vector<int> cur = get(subset[i]);
    a[v][i] = cur.size();
    for (int j = 0; j < cur.size(); j++) {
      g[cur[j]].push_back({v, i});
      b[v][i].push_back(cur[j]);
    }
  }
}
int find_set(int v) {
  if (col[v] != v) {
    col[v] = find_set(col[v]);
  }
  return col[v];
}
void union_set(int first, int second) { col[second] = first; }
bool used[N];
int n;
vector<int> e[N];
bool check(vector<pair<int, int>> &ans) {
  for (int i = 0; i < ans.size(); i++) {
    e[ans[i].first].push_back(ans[i].second);
    e[ans[i].second].push_back(ans[i].first);
  }
  for (int i = 1; i <= n; i++) {
    if (e[i].size() != a[i].size()) {
      return false;
    }
  }
  return true;
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    string s;
    cin >> s;
    parse(i, s);
  }
  for (int i = 1; i <= n; i++) {
    col[i] = -1;
  }
  queue<int> q;
  for (int i = 1; i <= n; i++) {
    if (a[i].size() == 1) {
      q.push(i);
      col[i] = i;
      used[i] = true;
    }
  }
  if (q.size() == n) {
    if (n == 2) {
      cout << "1\n1 2";
    } else {
      cout << "-1";
    }
    return 0;
  }
  vector<pair<int, int>> ans;
  while (!q.empty()) {
    int v = q.front();
    used[v] = true;
    for (int i = 0; i < g[v].size(); i++) {
      pair<int, int> t = g[v][i];
      if (used[t.first]) {
        continue;
      }
      int cur = --a[t.first][t.second];
      if (cur == 0) {
        if (NumOfSubsets[t.first] == a[t.first].size()) {
          col[t.first] = t.first;
        }
        NumOfSubsets[t.first]--;
        if (NumOfSubsets[t.first] <= 1) {
          q.push(t.first);
        }
        vector<int> f;
        for (int i = 0; i < b[t.first][t.second].size(); i++) {
          int val = b[t.first][t.second][i];
          f.push_back(find_set(val));
        }
        sort((f).begin(), (f).end());
        for (int i = 1; i <= f.size(); i++) {
          if (i == f.size() || f[i] != f[i - 1]) {
            union_set(t.first, f[i - 1]);
            ans.push_back({f[i - 1], t.first});
          }
        }
      }
    }
    q.pop();
  }
  if (ans.size() != n - 1 || !check(ans)) {
    cout << "-1\n";
    return 0;
  }
  cout << ans.size() << "\n";
  for (int i = 0; i < ans.size(); i++) {
    cout << ans[i].first << " " << ans[i].second << "\n";
  }
}
