#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 50;
int n;
int tim;
int s[maxn];
int deg[maxn];
int vis[maxn];
int head[maxn];
bitset<maxn> a[maxn];
map<int, bool> mp[maxn];
vector<pair<int, int> > an;
struct edge {
  int to, nex;
  edge(int to = 0, int nex = 0) : to(to), nex(nex) {}
};
vector<edge> G;
inline void addedge(int u, int v) {
  if (mp[u].count(v)) return;
  mp[u][v] = 1;
  G.push_back(edge(v, head[u])), head[u] = G.size() - 1;
  G.push_back(edge(u, head[v])), head[v] = G.size() - 1;
  ++deg[u], ++deg[v];
  an.push_back(make_pair(u, v));
}
int Find(int x) {
  int re = -1;
  for (int i = 1; i <= n; ++i)
    if (a[i][x]) {
      if (re == -1 || s[re] > s[i]) re = i;
    }
  return re;
}
void solve() {
  memset(head, -1, sizeof(head));
  for (int i = 1; i <= n; ++i) {
    for (int j = i + 1; j <= n; ++j) {
      bitset<maxn> b = a[i] & a[j];
      if (b.count() != 2) continue;
      int x = -1;
      for (int k = 1; k <= n; ++k)
        if (b[k]) {
          if (x == -1)
            x = k;
          else {
            addedge(x, k);
            break;
          }
        }
    }
  }
  if (G.size() == 0) {
    for (int i = 2; i <= n; ++i) an.push_back(make_pair(1, i));
    return;
  }
  if (G.size() == 2) {
    int x = G[0].to, y = G[1].to;
    int k = -1;
    for (int i = 1; i <= n; ++i)
      if (!deg[i]) {
        int L = Find(i);
        if (k == -1 || a[L] == a[k]) {
          an.push_back(make_pair(x, i));
          k = L;
        } else {
          an.push_back(make_pair(y, i));
        }
      }
    return;
  }
  for (int i = 1; i <= n; ++i)
    if (!deg[i]) {
      int L = Find(i);
      vector<int> v;
      ++tim;
      for (int j = 1; j <= n; ++j)
        if (a[L][j]) {
          if (deg[j]) {
            v.push_back(j);
            vis[j] = tim;
          }
        }
      if (v.size() == 2) {
        an.push_back(make_pair(i, deg[v[0]] == 1 ? v[0] : v[1]));
        continue;
      }
      for (unsigned int j = 0; j < v.size(); ++j) {
        int u = v[j];
        int cnt = 0;
        for (int k = head[u]; ~k; k = G[k].nex) {
          if (vis[G[k].to] == tim) ++cnt;
        }
        if (cnt > 1) {
          an.push_back(make_pair(i, u));
          break;
        }
      }
    }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &s[i]);
    for (int j = 1; j <= s[i]; ++j) {
      int x;
      scanf("%d", &x);
      a[i].set(x);
    }
  }
  solve();
  for (unsigned int i = 0; i < an.size(); ++i) {
    printf("%d %d\n", an[i].first, an[i].second);
  }
  return 0;
}
