Problem:
Score : 2200 points

Problem Statement

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}

Sample Input 1

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

Sample Output 1

1 2
1 3
3 4
4 5

Sample Input 2

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

Sample Output 2

-1

Sample Input 3

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

Sample Output 3

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

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include<cstdio>
#include<cstring>
#include<vector>
#define inf 1e9
#define N 4000001
using namespace std;
int total1,total2,SS,TT,S,T;
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][3];
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,int z1)
{
	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 (v[i]&&!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 (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,inf);
	insert(S,T,0,inf);
	for (int i=S;i<=T;i++)
		if (du[i]>0) 
		{
			insert(SS,i,du[i],inf);insert(i,SS,0,inf);
		}
		else	
		{
			insert(i,TT,-du[i],inf);insert(TT,i,0,inf);
		}
	for (int i=S;i<=T;i++)
		for (int j=head2[i];j;j=nexts2[j])
		{
			int y=edge2[j];
			insert(i,y,up[j]-down[j],down[j]);
			insert(y,i,0,down[j]);
		}
}
int re_dinic()
{
	int maxflow=0;
	int flow;
	while (bfs())
		while ((flow=dinic(SS,inf))) maxflow+=flow;
	return maxflow;
}
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=1;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();
	if (maxflow==sum)
	{
		for (int i=2;i<=total2;i++)
		{
			if (v1[i]>=inf) continue;
			if (v1[i]+v[i^1]==1)
			{
				int u1=edge[i];
				int u2=edge[i^1];
				if (u1<u2)
				{
					int t=u1;u1=u2;u2=t;
				}
				u1=(u1+n-1)%n+1;
				u2=(u2+n-1)%n+1;
				ans[u1][0]++;
				ans[u1][ans[u1][0]]=u2;
			}
		}
		for (int i=1;i<n;i++) 
			printf("%d %d\n",ans[i][1],ans[i][2]);
//		printf("1\n");
	}
	else
		printf("-1\n");
}