#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

namespace io
{
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	inline void flush (){fwrite (obuf, 1, oS - obuf, stdout);oS = obuf;}
	inline void putc (char x){*oS ++ = x;if (oS == oT) flush ();}
	template <class I>
	inline void gi (I &x) {for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;}
	template <class I>
	inline void print (I x){
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;while(x) qu[++ qr] = x % 10 + '0',  x /= 10;while (qr) putc (qu[qr--]);}
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io::gi;
using io::putc;
using io::print;

const int Max_N(100050);

namespace G
{
	const int Max_V(200050);
	const int Max_E((100050 + 200050 + 100050) * 2);
	int V, S, T;
	int Head[Max_V], Total, To[Max_E], Next[Max_E], Cap[Max_E];
	inline void Add_Edge(int tot, int s, int t, int c)
	{
		To[tot] = t, Next[tot] = Head[s], Head[s] = tot, Cap[tot] = c;
	}
	inline void Add_Link(int s, int t, int c)
	{
		Total += 2, Add_Edge(Total, s, t, c), Add_Edge(Total ^ 1, t, s, 0);
	}
	int Cur[Max_V], Dist[Max_V], Q[Max_V];
	bool BFS()
	{
		memset(Dist, 0, sizeof(Dist)), Dist[Q[Q[0] = 1] = S] = 1;
		for (int ft = 1, u;ft <= Q[0];)
		{
			if ((u = Q[ft++]) == T)
				return true;
			for (int i = Head[u], v;i;i = Next[i])
				if (!Dist[v = To[i]] && Cap[i])
					Dist[Q[++Q[0]] = v] = Dist[u] + 1;
		}
		return false;
	}
	int DFS(int u, int a)
	{
		if (u == T || a == 0)
			return a;
		int Ans(0);
		for (int &i = Cur[u], v, f;i;i = Next[i])
			if (Dist[v = To[i]] == Dist[u] + 1 && (f = DFS(v, min(a, Cap[i]))) > 0)
			{
				Ans += f, Cap[i] -= f, Cap[i ^ 1] += f;
				if ((a -= f) == 0)
					break;
			}
		return Ans;
	}
	int Dinic()
	{
		int Ans(0);
		while (BFS())
		{
			for (int i = 1;i <= V;++i)
				Cur[i] = Head[i];
			Ans += DFS(S, 0X3F3F3F3F);
		}
		return Ans;
	}
}

int N, Father[Max_N * 2], P[Max_N * 2], Q[Max_N], U[Max_N * 2], V[Max_N * 2];
vector<int> A[Max_N * 2], In[Max_N * 2];
bool done[Max_N * 2];

int Get_Father(int x)
{
	return Father[x] == x ? x : Father[x] = Get_Father(Father[x]);
}

int main()
{
	gi(N);
	G::V = N + (N - 1) + 2, G::S = N + (N - 1) + 1, G::T = N + (N - 1) + 2;
	for (int u = 1;u <= N;++u)
		Father[u] = u, G::Add_Link(G::S, u, 1);
	for (int i = N + 1, c;i <= N + (N - 1);++i)
	{
		Father[i] = i, gi(c), G::Add_Link(i, G::T, 1);
		for (int u;c--;)
		{
			gi(u), In[u].push_back(i), A[i].push_back(u), Father[Get_Father(u)] = i;
			if (u != 1)
				G::Add_Link(u, i, 1);
		}
	}
	for (int i = 1;i <= N + (N - 1);++i)
		if (Get_Father(i) != Get_Father(1))
		{
			print(-1);
			return 0;
		}
	if (G::Dinic() == N - 1)
	{
		for (int u = 2;u <= N;++u)
			for (int i = G::Head[u];i;i = G::Next[i])
				if (N + 1 <= G::To[i] && G::To[i] <= N + (N - 1) && G::Cap[i] == 0)
					P[u] = G::To[i];
		Q[Q[0] = 1] = 1;
		for (int u, ft = 1;ft <= Q[0];)
		{
			u = Q[ft++];
			for (int i = 0, t;i < In[u].size();++i)
				if (!done[t = In[u][i]])
				{
					done[t] = true;
					for (int j = 0, v;j < A[t].size();++j)
						if (P[v = A[t][j]] == t)
							U[t] = u, V[t] = v, Q[++Q[0]] = v;
				}
		}
		for (int i = N + 1;i <= N + (N - 1);++i)
			print(U[i]), putc(' '), print(V[i]), putc('\n');
	}
	else
		print(-1); 
	return 0;
}

Measured memory_bytes: 39424