//
// Created by 胡军军 on 2022/7/4.
//
#include<iostream>
#include<set>
#include<bitset>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
int n, m;
const int N = 1e3 + 1;
vector<int> edge[N];
int dfn[N], low[N], father[N], dfnCnt = 0;
bitset<N> vis;
void tarjan(int u, int pre) {
dfn[u] = low[u] = ++dfnCnt;
vis.set(u);
father[u] = pre;
for(int i = 0 ; i < edge[u].size() ; i++){
int v = edge[u][i];
if(!dfn[v]){
tarjan(v, u);
low[u] = min(low[u], low[v]);
}else if(pre!=v)
low[u] = min(low[u], dfn[v]);
}
}
void findBridge() {
vector<pair<int, int> > bridge;
for (int v = 0; v <= n; v++) {//下层
int u = father[v]; // 上层
// 桥:下层的最低 都无法到达 上层
if (~u && low[v] > dfn[u]) { //不是开始点 只要满足 桥的要求
if (v < u) // 小的在前
bridge.push_back(make_pair(v, u));
else
bridge.push_back(make_pair(u, v));
}
}
// 排序输出
sort(bridge.begin(),bridge.end());
printf("%d critical links\n",bridge.size());
for (vector<pair<int, int> >::iterator it = bridge.begin(); it != bridge.end(); it++)
printf("%d - %d\n",it->first,it->second);
printf("\n");
}
int main() {
int amt = 0;
while(scanf("%d", &n)!=EOF){
if(n==0) break;
amt++;
//初始化
for (int i = 0; i < n; i++) {
edge[i].clear();
dfn[i] = low[i] = 0;
}
dfnCnt = 0;
vis.reset();
//输入边
int u, v, k;
for (int i = 0; i < n; ++i) {
scanf("%d (%d)", &u, &k);
while (k--) {
cin >> v;
edge[u].push_back(v);
edge[v].push_back(u);
}
}
// tarjan算法
for (int i = 0; i < n; i++)
if (!dfn[i])
tarjan(i, -1);
findBridge(); // 寻找桥
}
if(amt==1) // 样例点错误,特判!!!
printf("%d critical links\n\n",0);
return 0;
}