#include<cstdio>
#include<cstring>
#include<vector>
#define inf 1e9
#define N 4000001
using namespace std;
int total1,total2,SS,TT,S,T;
int father[N],getsp[N];
int nexts[N],head[N],edge[N],v1[N],v[N],nexts2[N],head2[N],edge2[N],down[N],up[N];
int du[N],h[N],d[N],out[N],in[N],ans[N][15];
int n;
vector<int>s[N];
int max(int x,int y)
{
	if (x<y) return y;
	else	return x;
}
int min(int x,int y)
{
	if (x>y) return y;
	else	return x;
}
void insert(int x,int y,int z)
{
//	if(total2%2==1)
//	printf("%d %d %d\n",x,y,z);
	total2++;
	nexts[total2]=head[x];
	head[x]=total2;
	edge[total2]=y;
	v[total2]=z;
//	v1[total2]=z1;
}
void insert2(int x,int y,int l,int r)
{
//	printf("%d %d %d %d\n",x,y,l,r);
	total1++;
	nexts2[total1]=head2[x];
	head2[x]=total1;
	edge2[total1]=y;
	down[total1]=l;
	up[total1]=r;
	out[x]+=l;in[y]+=l;
}
bool bfs()
{
	memset(d,0,sizeof(d));
	int l=1,r=1;
	h[1]=SS;
	d[SS]=1;
	while (l<=r)
	{
		int u=h[l];
		for (int i=head[u];i;i=nexts[i])
		{
			int y=edge[i];
			if (y>TT) continue;
			if (v[i]>0&&!d[y])
			{
				r++;
				h[r]=y;
				d[y]=d[u]+1;
				if (y==TT) return true;
			}
		}
		l++;
	}
	return false;
}
int dinic(int k,int flow)
{ 
	if (k==TT) return flow;
	int rest=flow;
	for (int i=head[k];i && rest;i=nexts[i])
	{
		int y=edge[i];
		if (y>TT) continue;
		if (v[i]&&d[y]==d[k]+1)
		{
			int cost;
			if (rest>v[i]) cost=v[i];
			else	cost=rest;
			int pay=dinic(y,cost);
			if (pay==0) d[y]=0;
			rest-=pay;
			v[i]-=pay;
			v[i^1]+=pay;
		}
	}
	return flow-rest;
}
void restructure()
{
	SS=T+1;
	TT=SS+1;
	for (int i=S;i<=T;i++)
		du[i]=in[i]-out[i];
	total2=1;
	insert(T,S,inf);
	insert(S,T,0);
	for (int i=S;i<=T;i++)
		if (du[i]>0) 
		{
			insert(SS,i,du[i]);insert(i,SS,0);
		}
		else	
		{
			insert(i,TT,-du[i]);insert(TT,i,0);
		}
	for (int i=S;i<=T;i++)
		for (int j=head2[i];j;j=nexts2[j])
		{
			int y=edge2[j];
			if (i==6&&y==11)
			{
				T++;T--;
			}
			insert(i,y,up[j]-down[j]);
			insert(y,i,0);
		}
}
int re_dinic(int start)
{
	int maxflow=0;
	int flow;
	while (bfs())
		while ((flow=dinic(start,inf))) maxflow+=flow;
	return maxflow;
}
void dfs2(int k,int fa)
{
	for (int i=head2[k+n];i;i=nexts2[i])
	{
		int y=edge2[i];
		if (father[y]==0)
		{
			father[y]=k;
			dfs2(getsp[y],k);
		}
	}
}
int main()
{
	S=0;
	scanf("%d",&n);
	T=n*4+1;
	total1=1;
	memset(out,0,sizeof(out));
	memset(in,0,sizeof(in));
	insert2(S,1,0,1e9);
	for (int i=2;i<=n;i++)
	{
		insert2(i,i+n,1,1e9);
	//	insert2(i+n,i,1,1e9);	
		insert2(i+n,T,0,1e9);
	}
	for (int i=1;i<n;i++)
	{
		insert2(i+2*n,i+3*n,1,1);
	//	insert2(i+3*n,i+2*n,1,1);
	}
	for (int i=1;i<n;i++)
	{
	//	int p;
		s[i].resize(1);
		scanf("%d",&s[i][0]);
		s[i].resize(s[i][0]+1);
		for (int j=1;j<=s[i][0];j++) 	scanf("%d",&s[i][j]);
		for (int j=1;j<=s[i][0];j++)
		{
			insert2(s[i][j]+n,i+2*n,0,1);
			insert2(i+3*n,s[i][j],0,1);
		}
	}
	restructure();
	int sum=0;
	for (int i=S;i<=T;i++)	if (du[i]>=0) sum+=du[i];
	int maxflow=re_dinic(SS);
	if (maxflow==sum)
	{
		total1=1;
		SS=S=0;TT=T=2*n+1;
		memset(head,0,sizeof(head));
		memset(nexts,0,sizeof(nexts));
		memset(edge,0,sizeof(edge));
		memset(v,0,sizeof(v));
		total2=1;
		memset(head2,0,sizeof(head2));
		memset(edge2,0,sizeof(edge2));
		memset(nexts2,0,sizeof(nexts2));
		for (int i=1;i<n;i++)
		{
			insert(SS,i,1);
			insert(i,SS,0);
		//	printf("%d %d %d\n",SS,i,1); 
			for (int j=1;j<=s[i][0];j++)
			{
				insert2(s[i][j]+n,i,0,0);
				if (s[i][j]==1) continue;
			//	printf("%d %d %d\n",i,s[i][j]+n,1);
				insert(i,s[i][j]+n,1);
				insert(s[i][j]+n,i,0);
			}
		}
		for (int i=1;i<=n;i++)
		{
			insert(i+n,TT,1);
			insert(TT,i+n,0);
		//	printf("%d %d %d\n",i+n,TT,1);
		}
		maxflow=re_dinic(SS);
		for (int i=1;i<n;i++)
		{
			for (int j=head[i];j;j=nexts[j])
			{
				int y=edge[j];
			//	printf("%d %d %d\n",i,y,v[j^1]);
				if (j%2==0&&v[j]==0)
				{
					getsp[i]=y-n;
				}
			} 
		}
		memset(father,0,sizeof(father));
		//stotal=0;
		dfs2(1,0);
		for (int i=1;i<n;i++)
		{
			printf("%d %d\n",getsp[i],father[i]);
		}
	}
	else
	{
		printf("-1\n");
	}
}

Measured memory_bytes: 287752