You are given N-1 subsets of \\{1,2,...,N\\}. Let the i-th set be E_i.

Let us choose two distinct elements u_i and v_i from each set E_i, and consider a graph T with N vertices and N-1 edges, whose vertex set is \\{1,2,..,N\\} and whose edge set is (u_1,v_1),(u_2,v_2),...,(u_{N-1},v_{N-1}). Determine if T can be a tree by properly deciding u_i and v_i. If it can, additionally find one instance of (u_1,v_1),(u_2,v_2),...,(u_{N-1},v_{N-1}) such that T is actually a tree.

Constraints

* 2 \leq N \leq 10^5
* E_i is a subset of \\{1,2,..,N\\}.
* |E_i| \geq 2
* The sum of |E_i| is at most 2 \times 10^5.

Input

Input is given from Standard Input in the following format:


N
c_1 w_{1,1} w_{1,2} ... w_{1,c_1}
:
c_{N-1} w_{N-1,1} w_{N-1,2} ... w_{N-1,c_{N-1}}


Here, c_i stands for the number of elements in E_i, and w_{i,1},...,w_{i,c_i} are the c_i elements in c_i. Here, 2 \leq c_i \leq N, 1 \leq w_{i,j} \leq N, and w_{i,j} \neq w_{i,k} (1 \leq j < k \leq c_i) hold.

Output

If T cannot be a tree, print `-1`; otherwise, print the choices of (u_i,v_i) that satisfy the condition, in the following format:


u_1 v_1
:
u_{N-1} v_{N-1}

Output

If T cannot be a tree, print `-1`; otherwise, print the choices of (u_i,v_i) that satisfy the condition, in the following format:


u_1 v_1
:
u_{N-1} v_{N-1}

Examples

Input

5
2 1 2
3 1 2 3
3 3 4 5
2 4 5


Output

1 2
1 3
3 4
4 5


Input

6
3 1 2 3
3 2 3 4
3 1 3 4
3 1 2 4
3 4 5 6


Output

-1


Input

10
5 1 2 3 4 5
5 2 3 4 5 6
5 3 4 5 6 7
5 4 5 6 7 8
5 5 6 7 8 9
5 6 7 8 9 10
5 7 8 9 10 1
5 8 9 10 1 2
5 9 10 1 2 3


Output

1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
/*Lucky_Glass*/
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=1e5,INF=(1<<29),SZ=2*N+10;

struct EDGE{
    int to,cap;
    EDGE *nxt,*rev;
    EDGE(){}
    EDGE(int _t,int _c,EDGE *_n,EDGE *_r):to(_t),cap(_c),nxt(_n),rev(_r){}
};
struct GRAPH{
    EDGE edg[4*N*2+10],*head[SZ],*ncnt;
    GRAPH(){ncnt=edg;}
    void AddEdge(int u,int v,int cap){
        EDGE *p=++ncnt,*q=++ncnt;
        *p=EDGE(v,cap,head[u],q);head[u]=p;
        *q=EDGE(u,  0,head[v],p);head[v]=q;
    }
    EDGE* operator [](int id){return head[id];}
};
GRAPH Gr;
EDGE *cop[SZ];
int dis[SZ];
vector< pair<int,int> > lnk[N+3];
int n,S,T,tot;
vector<int> tset[N+3];
int ans[N+3][2];
bool vis[N+3];

int Aug(int u,int in){
    if(u==T) return in;
    int out=0;
    while(cop[u]){
        EDGE *it=cop[u];cop[u]=cop[u]->nxt;
        int v=it->to;
        if(dis[v]!=dis[u]+1 || it->cap<=0) continue;
        int tov=Aug(v,min(in-out,it->cap));
        it->cap-=tov;it->rev->cap+=tov;
        out+=tov;
        if(out==in) break;
    }
    return out;
}
bool BFS(){
    for(int i=1;i<=T;i++) dis[i]=-1,cop[i]=Gr[i];
    queue<int> que;que.push(S);dis[S]=0;
    while(!que.empty()){
        int u=que.front();que.pop();
        for(EDGE *it=Gr[u];it;it=it->nxt){
            int v=it->to;
            if(dis[v]!=-1 || it->cap<=0) continue;
            dis[v]=dis[u]+1;
            if(v==T) return true;
            que.push(v);
        }
    }
    return false;
}
int Dinic(){
    int res=0;
    while(BFS())
        res+=Aug(S,INF);
    return res;
}
void DFS(int u){
    vis[u]=true;tot++;
    for(int i=(int)lnk[u].size()-1;i>=0;i--){
        int v=lnk[u][i].first,id=lnk[u][i].second;
        if(ans[id][0] || vis[v]) continue;
        ans[id][0]=u;ans[id][1]=v;
        DFS(v);
    }
}
int main(){
    // freopen("input.txt","r",stdin);
    scanf("%d",&n);
    S=n*2;T=S+1;
    for(int i=2;i<=n;i++) Gr.AddEdge(S,i,1);
    for(int i=1;i<n;i++) Gr.AddEdge(i+n,T,1);
    for(int i=1;i<n;i++){
        int num;scanf("%d",&num);
        while(num--){
            int u;scanf("%d",&u);
            Gr.AddEdge(u,n+i,1);
            tset[i].push_back(u);
        }
    }
    int res=Dinic();
    if(res<n-1) printf("-1\n");
    else{
        for(int i=1;i<n;i++){
            int E=i+n,u=-1;
            for(EDGE *it=Gr[E];it && u==-1;it=it->nxt)
                if(it->cap)
                    u=it->to;
            for(int j=(int)tset[i].size()-1;j>=0;j--)
                if(tset[i][j]!=u){
                    int v=tset[i][j];
                    lnk[u].emplace_back(v,i);
                    lnk[v].emplace_back(u,i);
                }
        }
        DFS(1);
        if(tot<n) printf("-1\n");
        else
            for(int i=1;i<n;i++)
                printf("%d %d\n",ans[i][0],ans[i][1]);
    }
    return 0;
}
