#include<iostream> //头文件
using namespace std; //名字空间
const int MAXN=110; //定义常量,是个好习惯
int n,s,ans=1000000,start,ls[MAXN],num[MAXN][2],a[MAXN][2][10];
//a数组第一维表示该篱笆编号,
//第二维表示链接左端还是右端,
//第三维表示连接篱笆的编号。
int checkdir(int s,int t) { //当前边,现在搜到的编号
for (int i=1; i<=num[t][0]; i++) { //遍历总数
if (a[t][0][i]==s) return 0; //返回右端
}
return 1; //返回左端
}
void dfs(int u, int dir, int sum) { //开始爆搜,变量下面调用时解释过了
if (sum>ans) return; //ans是最优解,如果当前大于它了,就没必要继续进行
if (u==start && sum>0) { //重又回到起点,即形成环路
ans=sum; //记录最优解
return; //返回
}
for (int i=1; i<=num[u][dir]; i++) { //遍历该端链接的每条边
dfs(a[u][dir][i],1-checkdir(u,a[u][dir][i]),sum+ls[u]); //搜下去,中间的checkdir是用来确认现在该走哪一端了
}
}
int main() { //主函数
cin>>n; //读入总边数
for (int zz=1; zz<=n; zz++) { //for循环读入
cin>>s; //当前边的编号
cin>>ls[s]>>num[s][0]>>num[s][1]; //该边的长度,左端连的总个数,有端连的总个数
for (int i=1; i<=num[s][0]; i++) cin>>a[s][0][i]; //读入左端连的编号
for (int i=1; i<=num[s][1]; i++) cin>>a[s][1][i]; //读入右端连的编号
}
for (start=1; start<=n; start++) { //爆搜每条边
dfs(start,0,0); //起边为start,当前是哪一端,当前总长度
}
cout<<ans<<endl; //输出答案
return 0; //返回
}