#include <bits/stdc++.h>

using std::pair;
using std::vector;
using std::string;

typedef long long ll;
typedef pair<int, int> pii;

#define fst first
#define snd second
#define pb(a) push_back(a)
#define mp(a, b) std::make_pair(a, b)
#define debug(...) fprintf(stderr, __VA_ARGS__)

template <typename T> bool chkmax(T& a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> bool chkmin(T& a, T b) { return a > b ? a = b, 1 : 0; }

const int oo = 0x3f3f3f3f;

string procStatus() {
    std::ifstream t("/proc/self/status");
    return string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
}

template <typename T> T read(T& x) {
    int f = 1; x = 0;
    char ch = getchar();
    for(;!isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    return x *= f;
}

const int N = 200000;
const int M = N << 4;

int S, T;

struct edge {
    int to, nxt, cap;
};

edge e[M + 5];
int st[N + 5], ecnt = 1;

void addedge(int u, int v, int c) {
    e[++ ecnt] = (edge) { v, st[u], c }, st[u] = ecnt;
    e[++ ecnt] = (edge) { u, st[v], 0 }, st[v] = ecnt;
}

int cur[N + 5], dis[N + 5];

bool bfs() {
    static int que[N + 5];
    int head = 0, tail = 0;

    memset(dis, 0xff, sizeof dis);
    dis[que[tail ++] = S] = 0;

    while(head < tail) {
        int x = que[head ++];
        for(int i = st[x]; i; i = e[i].nxt) if(e[i].cap) {
            int y = e[i].to;
            if(dis[y] == -1) {
                dis[y] = dis[x] + 1;
                que[tail ++] = y;
            }
        }
    }
    return ~dis[T];
}

int dfs(int x, int flow) {
    if(x == T || !flow) {
        return flow;
    }

    int res = 0;
    for(int &i = cur[x]; i; i = e[i].nxt) {
        int y = e[i].to, aug;
        if(dis[y] == dis[x] + 1 && (aug = dfs(y, std::min(e[i].cap, flow)))) {
            res += aug;
            flow -= aug;
            e[i].cap -= aug;
            e[i ^ 1].cap += aug;
            if(!flow) break;
        }
    }
    return res;
}

int max_flow() {
    int ans = 0;
    while(bfs()) {
        memcpy(cur, st, sizeof cur);
        ans += dfs(S, oo);
    }
    return ans;
}

int n, cnt;
pii ans[N + 5];
int mat[N + 5];
bool vis[N + 5];
vector<int> g[N + 5];

void dfs(int u) {
    for(auto v : g[u]) if(!vis[v]) {
        ++ cnt;
        vis[v] = true;
        ans[v - n] = mp(u, mat[v]);
        dfs(mat[v]);
    }
}

int main() {
#ifdef Wearry
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif

    read(n);
    S = n << 1, T = S + 1;
    for(int i = 2; i <= n; ++i) {
        addedge(S, i, 1);
    }

    for(int i = 1; i < n; ++i) {
        static int c, x;

        for(read(c); c--; ) {
            read(x);
            g[x].pb(i + n);
            addedge(x, i + n, 1);
        }
        addedge(i + n, T, 1);
    }

    int mf = max_flow();

    if(mf < n - 1) return !puts("-1");

    for(int i = 2; i <= n; ++i) {
        for(int j = st[i]; j; j = e[j].nxt) {
            int t = e[j].to;
            if(!e[j].cap && t > n && t < 2*n) {
                mat[t] = i;
                break;
            }
        }
    }

    dfs(1);

    if(cnt < n - 1) {
        puts("-1");
    } else {
        for(int i = 1; i < n; ++i) {
            printf("%d %d\n", ans[i].fst, ans[i].snd);
        }
    }

    return 0;
}


Measured memory_bytes: 30720