#include<bits/stdc++.h>
using namespace std;
const int maxn=2e7+11;
int n,m;
struct E{
int f,t,v,n;
}edge[maxn];
int l,head[maxn];
struct P{
int f,t,n;
}protect[maxn];
int L,Head[maxn],rd[maxn];
int dis[maxn],into[maxn],arrive[maxn],vis[maxn];
struct Q{
int a;
friend bool operator < (Q a,Q b){return dis[a.a]>dis[b.a];}
};
priority_queue<Q> p;
void Dijeisila(int s){
for(int i=1;i<=n;i++){
dis[i]=arrive[i]=(1<<30);
}
dis[s]=into[s]=rd[s]=arrive[s]=0;
p.push(Q{s});
while(!p.empty()){
int q=p.top().a;
p.pop();
if(vis[q]) continue;
vis[q]=1;
for(int i=head[q];i;i=edge[i].n){
int t=edge[i].t;
if(dis[q]+edge[i].v<arrive[t]){
arrive[t]=dis[q]+edge[i].v;
if(!rd[t]){
dis[t]=max(arrive[t],into[t]);
p.push(Q{t});
}
}
}
for(int i=Head[q];i;i=protect[i].n){
int t=protect[i].t;
into[t]=max(into[t],dis[q]);
rd[t]--;
if(rd[t]==0){
dis[t]=max(into[t],arrive[t]);
p.push(Q{t});
}
}
}
}
void read(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int f,t,v;
scanf("%d%d%d",&f,&t,&v);
l++,edge[l]=(E){f,t,v,head[f]},head[f]=l;
}
for(int i=1;i<=n;i++){
int num;
scanf("%d",&num);
rd[i]=num;
for(int e=1;e<=num;e++){
int k;
scanf("%d",&k);
L++,protect[L]=(P){k,i,Head[k]},Head[k]=L;
}
}
Dijeisila(1);
printf("%d\n",dis[n]);
}
int main(){
read();
}
评测结果