#include <cmath>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <chrono>

using namespace std;

typedef long long ll;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

struct edge
{
    int a, b, cap, ind;
};

const int N = 4e5 + 7;

vector <int> g[N];
vector <edge> e;

void add(int a, int b, int c, int ind)
{
    g[a].push_back(e.size());
    e.push_back({a, b, c, ind});
}

void add_edge(int a, int b, int c, int ind)
{
    add(a, b, c, ind);
    add(b, a, 0, -1);
}

int dist[N];
int ptr[N];

int s, t;

int dfs(int v, int fl = 1e9)
{
    if (v == t)
    {
        return fl;
    }
    for (int &i = ptr[v]; i < (int) g[v].size(); i++)
    {
        int ind = g[v][i];
        if (dist[e[ind].b] == dist[v] + 1 && e[ind].cap > 0)
        {
            int go = dfs(e[ind].b, min(fl, e[ind].cap));
            if (go)
            {
                e[ind].cap -= go;
                e[ind ^ 1].cap += go;
                return go;
            }
        }
    }
    return 0;
}

bool bfs()
{
    for (int i = 0; i <= t; i++)
    {
        dist[i] = -1;
        ptr[i] = 0;
    }
    queue <int> q;
    q.push(s);
    dist[s] = 0;
    while (!q.empty())
    {
        int v = q.front();
        q.pop();
        for (int ind : g[v])
        {
            if (e[ind].cap > 0 && dist[e[ind].b] == -1)
            {
                dist[e[ind].b] = dist[v] + 1;
                q.push(e[ind].b);
            }
        }
    }
    return dist[t] != -1;
}

int main()
{
#ifdef ONPC
    freopen("a.in", "r", stdin);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    s = n + n;
    t = n + n + 1;
    int edg = 0;
    vector <vector <int> > g(n);
    vector <vector <int> > gr(n);
    for (int i = 0; i < n - 1; i++)
    {
        add_edge(s, i, 1, -1);
        int e;
        cin >> e;
        while (e--)
        {
            int v;
            cin >> v;
            v--;
            g[i].push_back(v);
            gr[v].push_back(i);
            add_edge(i, n - 1 + v, 1, edg++);
        }
    }
    for (int i = 0; i < n; i++) add_edge(n - 1 +  i, t, 1, -1);
    int ans = 0;
    while (bfs())
    {
        while (int x = dfs(s, 1e9))
        {
            ans += x;
        }
    }
    if (ans != n - 1)
    {
        cout << -1 << '\n';
        return 0;
    }
    vector <int> mt(n - 1, -1);
    vector <int> rmt(n, -1);
    vector <int> op(n - 1, -1);
    for (auto c : e)
    {
        if (c.ind != -1 && c.cap == 0)
        {
            int a = c.a, b = c.b - (n - 1);
            mt[a] = b;
            rmt[b] = a;
        }
    }
    set <int> q;
    for (int i = 0; i < n; i++) if (rmt[i] == -1) q.insert(i);
    set <int> t;
    for (int i = 0; i < n - 1; i++) t.insert(i);
    while (!q.empty())
    {
        int who = *q.begin();
        q.erase(who);
        vector <int> del;
        for (int ok : gr[who])
        {
            if (t.count(ok))
            {
                q.insert(mt[ok]);
                op[ok] = who;
                del.push_back(ok);
            }
        }
        for (int x : del) t.erase(x);
    }
    if (*min_element(op.begin(), op.end()) == -1)
    {
        cout << -1 << '\n';
        return 0;
    }
    for (int i = 0; i < n - 1; i++)
    {
        cout << mt[i] + 1 << ' ' << op[i] + 1 << '\n';
    }
    return 0;
}


Measured memory_bytes: 55652