#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using pii = pair<int, int>;
int n;
vector<int> adj[1010];
vector<vector<int>> lists[1010];
int sz[1010][1010];
char line[10 * 1010];
int nextInt(char *line, int &pos) {
  int x;
  for (x = 0; '0' <= line[pos] && line[pos] <= '9'; ++pos)
    x = x * 10 + line[pos] - '0';
  return x;
}
void parseLine(char *line, int v) {
  int pos, nr;
  vector<int> list;
  for (pos = 0; line[pos] != '\0';) {
    nr = nextInt(line, pos);
    list.clear();
    while (nr--) {
      ++pos;
      list.emplace_back(nextInt(line, pos));
    }
    for (auto u : list) sz[v][u] = list.size();
    lists[v].emplace_back(list);
    if (line[pos] == '-') ++pos;
  }
}
void addEdge(int v, int u) {
  adj[v].emplace_back(u);
  adj[u].emplace_back(v);
}
bool dfs(int v, int p = -1) {
  bool found;
  for (auto list : lists[v])
    if (find(list.begin(), list.end(), p) == list.end()) {
      found = false;
      for (auto u : list)
        if (sz[u][v] == n - list.size()) {
          if (!dfs(u, v)) return false;
          addEdge(v, u);
          if (!found)
            found = true;
          else
            return false;
        }
      if (!found) return false;
    }
  return true;
}
int main() {
  int i;
  cin >> n;
  for (i = 1; i <= n; ++i) {
    cin >> line;
    parseLine(line, i);
  }
  if (!dfs(1)) return cout << -1 << '\n', 0;
  cout << n - 1 << '\n';
  for (i = 1; i <= n; ++i)
    for (auto u : adj[i])
      if (i < u) cout << i << ' ' << u << '\n';
  return 0;
}
