#include <bits/stdc++.h>
using namespace std;
int bcnt[1 << 16], lbit[1 << 16];
inline unsigned f(unsigned x) { return x & ((1u << 16) - 1); }
inline unsigned s(unsigned x) { return x >> 16; }
inline int lowbit(unsigned x) { return f(x) ? lbit[f(x)] : lbit[s(x)] + 16; }
inline int bitcnt(unsigned x) { return bcnt[f(x)] + bcnt[s(x)]; }
struct info {
  unsigned val[32];
  unsigned& operator[](int x) { return val[x]; }
  info operator&(info b) {
    info c;
    for (int i = 0; i < 32; i++) c[i] = val[i] & b[i];
    return c;
  }
  int size() {
    int S = 0;
    for (int i = 0; i < 32; i++) S += bitcnt(val[i]);
    return S;
  }
  bool operator()(int x) { return (val[x >> 5] >> (x & 31)) & 1; }
  bool operator==(info b) {
    for (int i = 0; i < 32; i++)
      if (val[i] != b[i]) return 0;
    return 1;
  }
  bool operator!=(info b) {
    for (int i = 0; i < 32; i++)
      if (val[i] != b[i]) return 1;
    return 0;
  }
};
info a[1005];
bool vis[1005], leaf[1005];
info Vis;
vector<pair<int, int> > e;
info b[1005];
void addedge(int x, int y) {
  if (b[x](y)) return;
  b[y][x >> 5] |= 1u << (x & 31);
  b[x][y >> 5] |= 1u << (y & 31);
  Vis[x >> 5] |= 1u << (x & 31);
  Vis[y >> 5] |= 1u << (y & 31);
  x++;
  y++;
  vis[x] = vis[y] = 1;
  e.push_back(make_pair(x, y));
}
int main() {
  lbit[0] = -10000000;
  for (int i = 1; i < (1 << 16); i++)
    bcnt[i] = (i & 1) + bcnt[i >> 1], lbit[i] = (i & 1 ? 0 : lbit[i >> 1] + 1);
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int k;
    scanf("%d", &k);
    for (int j = 1; j <= k; j++) {
      int x;
      scanf("%d", &x);
      x--;
      a[i][x >> 5] |= 1u << (x & 31);
    }
  }
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++) {
      info t = (a[i] & a[j]);
      if (t.size() != 2) continue;
      int fst = -1;
      for (int k = 0; k < 32; k++) {
        unsigned x = t[k];
        while (x) {
          if (fst != -1)
            addedge(fst, (k << 5) | lowbit(x));
          else
            fst = (k << 5) | lowbit(x);
          x ^= 1u << lowbit(x);
        }
      }
    }
  if (e.size() == 0) {
    for (int i = 2; i <= n; i++) printf("%d %d\n", i, 1);
    return 0;
  }
  if (e.size() == 1) {
    printf("%d %d\n", e[0].first, e[0].second);
    int fl = -1;
    for (int i = 1; i <= n; i++)
      if (a[i].size() < n) {
        if (fl == -1) {
          fl = i;
          for (int j = 1; j <= n; j++)
            if (!vis[j] && a[i](j - 1)) printf("%d %d\n", e[0].first, j);
        }
        if (fl != -1 && a[i] != a[fl]) {
          for (int j = 1; j <= n; j++)
            if (!vis[j] && a[i](j - 1)) printf("%d %d\n", e[0].second, j);
          break;
        }
      }
    return 0;
  }
  for (int i = 1; i <= n; i++)
    if (vis[i]) b[i - 1][(i - 1) >> 5] |= 1 << ((i - 1) & 31);
  for (int i = 0; i < e.size(); i++) printf("%d %d\n", e[i].first, e[i].second);
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      int mn = 1e9, mnj = -1;
      for (int j = 1; j <= n; j++)
        if (a[j](i - 1) && a[j].size() < mn) mn = a[j].size(), mnj = j;
      info t = (a[mnj] & Vis);
      for (int j = 1; j <= n; j++)
        if (vis[j] && b[j - 1] == t) printf("%d %d\n", i, j);
    }
  return 0;
}
