#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <queue>

  int n, m, u, v, k, t, x;
  std::vector <std::vector <std::pair <int, int> > > G(100001);
  std::set <int> st[100001];
  std::queue <int> q;
  bool vis[100001];
  long long prices[100001];

  void BFS(int time, int node)
  {
  	  int value = time;
  	  while (st[node].find(value) != st[node].end() && node != n)
	  {
	  	  value++;
	  }

  	  for (int i = 0; i < G[node].size(); i++)
  	  {
  		  if (value + G[node][i].second < prices[G[node][i].first])
  		  {
  		  	  q.push(G[node][i].first);
		      prices[G[node][i].first] = value + G[node][i].second;
  		  }
  	  }
  }

int main()
{
	std::cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		scanf ("%d %d %d", &u, &v, &t);
		G[u].push_back(std::make_pair(v, t));
		G[v].push_back(std::make_pair(u, t));
	}

	for (int i = 1; i <= n; i++)
	{
		scanf ("%d", &k);
		while (k--)
		{
			scanf ("%d", &x);
			st[i].insert(x);
		}
		prices[i] = 1000000000000000000;
	}
	prices[1] = 0;

	q.push(1);
	while (!q.empty())
	{
		int member = q.front();
		q.pop();
		BFS(prices[member], member);
	}

	if (prices[n] == 1000000000000000000)
		std::cout << -1;
	else
		std::cout << prices[n];

	return 0;
}


//lxrtxdy!
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

int n,m;
int k;
const int N = 1e5 + 10;

vector<pair<int,int>>edge[N];
vector<int>v[N];

long long dist[N];
bool st[N];

void spfa()
{
    memset(dist,0x3f,sizeof dist);
    dist[1] = 0;
    queue<int>q;
    q.push(1);

    while(q.size())
    {
        int t = q.front();
        q.pop();
        st[t] = false;

        int d = dist[t];

        for(auto &x : v[t])
        {
            if(x == d)
            {
                d = x + 1;
            }
        }

        for(auto &x : edge[t])
        {
            int ver = x.first,dis = x.second;

            if(dist[ver] > d + dis)
            {
                dist[ver] = d + dis;

                if(!st[ver])
                {
                    q.push(ver);
                    st[ver] = true;
                }
            }
        }
    }

}

int main()
{
    scanf("%d%d",&n,&m);

    for(int i = 0;i < m;i ++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        edge[a].push_back({b,c});
        edge[b].push_back({a,c});
    }

    for(int i = 1;i <= n;i ++)
    {
        cin >> k;
        for(int j = 0;j < k;j ++)
        {
            int x;
            cin >> x;
            v[i].push_back(x);
        }
    }

    spfa();
    if(dist[n] >= 0x3f3f3f3f)cout << -1 << endl;
    else
    cout << dist[n] << endl;

    return 0;
}

//orzlxr!//hello//hello


#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#define mp make_pair
#define pb push_back
using namespace std;

const int N = 200010;
int n, m;
long long dis[N];
bool vis[N];
vector<pair<int, int> >g[N];
map<pair<int, long long>, long long>M;

struct node {
  long long dist;
  int u;
  inline bool operator < (const node &p) const {
    return dist > p.dist;
  }
};

long long Solve(void) {
  fill(vis + 1, vis + 1 + n, 0);
  fill(dis + 1, dis + 1 + n, -1);
  priority_queue<node>q;
  dis[1] = M[mp(1, 0)];
  q.push((node){0LL, 1});
  while (!q.empty()) {
    node now = q.top();
    q.pop();
    int x = now.u;
    if (vis[x]) continue;
    vis[x] = 1;
    for (int i = 0; i < (int)g[x].size(); ++i) {
      int y = g[x][i].first, d = g[x][i].second;
      long long tmp = M[mp(y, dis[x] + d)];
      if (tmp == 0 || y == n) tmp = dis[x] + d;
      if (dis[y] == -1 || dis[y] > tmp)
	dis[y] = tmp, q.push((node){tmp, y});
    }
  }
  return dis[n];
}

int main(void) {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    g[x].pb(mp(y, z));
    g[y].pb(mp(x, z));
  }
  for (int x = 1; x <= n; ++x) {
    int num, t[N], p = 1;
    scanf("%d", &num);
    for (int i = 1; i <= num; ++i) {
      scanf("%d", t + i);
      if (i > 1 && t[i] - t[i - 1] > 1) {
	for (int j = p; j < i; ++j)
	  M[mp(x, t[j])] = t[i - 1] + 1;
	p = i;
      }
    }
    for (int i = p; i <= num; ++i)
      M[mp(x, t[i])] = t[num] + 1;
  }
  printf("%lld\n", Solve());

  return 0;
}


#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#define mp make_pair
#define pb push_back
using namespace std;

const int N = 200010;
int n, m;
long long dis[N];
bool vis[N];
vector<pair<int, int> >g[N];
map<pair<int, long long>, long long>M;

struct node {
  long long dist;
  int u;
  inline bool operator < (const node &p) const {
    return dist < p.dist;
  }
};

long long Solve(void) {
  fill(vis + 1, vis + 1 + n, 0);
  fill(dis + 1, dis + 1 + n, -1);
  priority_queue<node>q;
  dis[1] = M[mp(1, 0)];
  q.push((node){0LL, 1});
  while (!q.empty()) {
    node now = q.top();
    q.pop();
    int x = now.u;
    if (vis[x]) continue;
    vis[x] = 1;
    for (int i = 0; i < (int)g[x].size(); ++i) {
      int y = g[x][i].first, d = g[x][i].second;
      long long tmp = M[mp(y, now.dist + d)];
      if (tmp == 0 || y == n) tmp = now.dist + d;
      if (dis[y] == -1 || dis[y] > tmp)
	dis[y] = tmp, q.push((node){tmp, y});
    }
  }
  return dis[n];
}

int main(void) {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    g[x].pb(mp(y, z));
    g[y].pb(mp(x, z));
  }
  for (int x = 1; x <= n; ++x) {
    int num, t[N], p = 1;
    scanf("%d", &num);
    for (int i = 1; i <= num; ++i) {
      scanf("%d", t + i);
      if (i > 1 && t[i] - t[i - 1] > 1) {
	for (int j = p; j < i; ++j)
	  M[mp(x, t[j])] = t[i - 1] + 1;
	p = i;
      }
    }
    for (int i = p; i <= num; ++i)
      M[mp(x, t[i])] = t[num] + 1;
  }
  printf("%lld\n", Solve());

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int Nmax = 1e5 + 5;

set < pair < int , int > > S;
set < pair < int , int > > ::iterator it;

int n , m , d[Nmax];

vector < pair < int , int > > L[Nmax];

set < int > C[Nmax];
set < int > :: iterator it1;

int main()
{
    int x , y , c;
    cin >> n >> m;
    for(int i = 1 ; i <= m ; i++)
    {
        cin >> x >> y >> c;
        L[x].push_back({y , c});
        L[y].push_back({x , c});
    }
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> x;
        for(int j = 1 ; j <= x ; j++)
        {
            cin >> y;
            C[i].insert(y);
        }
    }
    for(int i = 1 ; i <= n ; i++)
        d[i] = LONG_MAX;
    d[1] = 0;
    S.insert({d[1] , 1});
    while(!S.empty())
    {
        it = S.begin();
        x = it->first;
        y = it->second;
        S.erase(it);
        it1 = C[y].find(x);
        while(it1 != C[y].end())
        {
            x++;
            it1 = C[y].find(x);
        }
        for(auto p : L[y])
            if(d[p.first] > x + p.second)
        {
            d[p.first] = x + p.second;
            S.insert({d[p.first] , p.first});
        }
    }
    if(d[n] == LONG_MAX)
        cout << "-1\n";
    else cout << d[n] << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int Nmax = 1e5 + 5;

set < pair < int , int > > S;
set < pair < int , int > > ::iterator it;

int n , m , d[Nmax];

vector < pair < int , int > > L[Nmax];

set < int > C[Nmax];
set < int > :: iterator it1;

int main()
{
    int x , y , c;
    cin >> n >> m;
    for(int i = 1 ; i <= m ; i++)
    {
        cin >> x >> y >> c;
        L[x].push_back({y , c});
        L[y].push_back({x , c});
    }
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> x;
        for(int j = 1 ; j <= x ; j++)
        {
            cin >> y;
            C[i].insert(y);
        }
    }
    for(int i = 1 ; i <= n ; i++)
        d[i] = 1e9;
    d[1] = 0;
    S.insert({d[1] , 1});
    while(!S.empty())
    {
        it = S.begin();
        x = it->first;
        y = it->second;
        S.erase(it);
        it1 = C[y].find(x);
        while(it1 != C[y].end())
        {
            x++;
            it1 = C[y].find(x);
        }
        for(auto p : L[y])
            if(d[p.first] > x + p.second)
        {
            d[p.first] = x + p.second;
            S.insert({d[p.first] , p.first});
        }
    }
    if(d[n] == 1e9)
        cout << "-1\n";
    else cout << d[n] << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
using namespace std;
int n,m;
vector<int> vs[100005];
vector<int> gaps[100005];

vector<pair<int,int> > gs[100005];

int findbest(int x,int t){
	int l = 0,h = vs[x].size(),m;
	int ret = 1<<30;
	if(vs[x][l] > t || vs[x][h-1] < t)
			return 0;

	while(h-l > 1){
		m = (l+h)/2;
		cout<<l<<" "<<h<<" "<<m<<" "<<vs[x][m]<<" "<<ret<<endl;
		if(vs[x][m] <= t){
		//	l = m;
			int y = (m+h)/2;
			if(vs[x][y] < t) l = m;
			else h = m;
		}
		else{
		int y = (m+l)/2;
	if(vs[x][y] > t){
		h = m;
			}else l = m;
		}

	if(vs[x][m] > t && vs[x][m-1] < t) return t;

	if(vs[x][m] > t && vs[x][m] - 1!= vs[x][m-1])
		ret = min(vs[x][m] - 1,ret),cout<<"***"<<ret<<endl;

	if(vs[x][m] <= t && vs[x][m] + 1!= vs[x][m+1] && vs[x][m] + 1 > t)
		ret = min(vs[x][m] + 1,ret);
	}
cout<<"***"<<l<<" "<<h<<" "<<m<<" "<<vs[x][m]<<endl;
	return ret != 1<<30? ret : vs[x][vs[x].size()-1] + 1;
}

priority_queue<pair<int,int> , vector<pair<int,int> > ,greater<pair<int,int> > >q;
pair<int,pair<int,int> > pss;
int d[100005];
void dij(){
pair<int,int> p,ps,pr;
p = {0,1};
d[1] = 0;
q.push(p);

while(!q.empty()){
pr = q.top();q.pop();
int x = pr.f;
int xs = x;
if(vs[pr.s].size()){
int z = lower_bound(vs[pr.s].begin(),vs[pr.s].end(),x)-vs[pr.s].begin();
    xs = vs[pr.s][z];
if(xs > x) xs = x;
else if(xs == x){
		xs = gaps[pr.s][lower_bound(gaps[pr.s].begin(),gaps[pr.s].end(),x)-gaps[pr.s].begin()];
//	cout<<pr.s<<"*********.."<<xs<<endl;
	}
}
	if(xs < x) xs = x;
//cout<<pr.s<<" "<<xs<<endl;
 if(pr.s == n) return ;
if(d[pr.s] != pr.f) continue;
for(int i = 0;i < gs[pr.s].size();i++){
	p = gs[pr.s][i];
	int cost = xs + p.s;//lower_bound(vs[p.f].begin(),vs[p.f].end(),d[pr.s] + p.s);

 // cout<<xs<<" "<<p.s<<" "<<p.f<<" "<<d[p.f]<<endl;

	if(d[p.f] > cost){
		d[p.f] = cost;
		ps = {cost,p.f};
		q.push(ps);
//	cout<<"***"<<p.f<<" "<<xs<<endl;

	}

}

}

}

int main(){
	//freopen("in.txt","r",stdin);
	cin >> n >> m;
	int x,y,z;
	pair<int,int>p;

	for(int i = 0;i < m ;i++){
		cin >> x >> y >> z;
		p = {y,z};
		gs[x].pb(p);
		p = {x,z};
		gs[y].pb(p);
	}
for(int i = 1;i <= n ;i++){
	d[i] = 1<<30;
	cin >> x;
	if(x){
		cin >> y;//y++;
		vs[i].pb(y);
		for(int j = 1; j < x;j++){
			cin >> z;//z++;
			if(y+1 != z)
			gaps[i].pb(y+1);
			y = z;
			vs[i].pb(z);
		}
		gaps[i].pb(y+1);
		//cout<<endl;
	}
}
		dij();
		cout<<(d[n] == 1<<30 ? -1:d[n])<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
vector<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int v_find(int a,int x)
{
    int l=0,r=T[a].size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(x<T[a][mid])
            r=mid;
        else if(x>T[a][mid])
            l=mid+1;
        else return mid;
    }
    return l;
}

void dijkstra()
{
    priority_queue<Node> Q;
    for(int i=0; i<=n; i++) d[i]=INF;
    d[0]=0;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > d[u]+e.w)
            {
                int now=d[u]+e.w;
                int flag=0;
                if(T[e.v].size()>0)
                {
                    flag=v_find(e.v,now);
                    if(T[e.v][flag]==now)
                    {
                        flag++;
                        while(T[e.v][flag]==T[e.v][flag-1]+1&&flag<T[e.v].size())
                        {
                            now++;
                            flag++;
                        }
                    }

                }
                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].push_back(t);
            }
        }
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
            printf("%d\n",d[n-1]);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
vector<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int v_find(int a,int x)
{
    int l=0,r=T[a].size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(x<T[a][mid])
            r=mid;
        else if(x>T[a][mid])
            l=mid+1;
        else return mid;
    }
    return l;
}

void dijkstra()
{
    priority_queue<Node> Q;
    for(int i=0; i<=n; i++) d[i]=INF;
    d[0]=0;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > d[u]+e.w)
            {
                int now=d[u]+e.w;
                int flag=0;
                if(T[e.v].size()>0&&e.v!=n-1)
                {
                    flag=v_find(e.v,now);
                    if(T[e.v][flag]==now)
                    {
                        flag++;
                        while(T[e.v][flag]==T[e.v][flag-1]+1&&flag<T[e.v].size())
                        {
                            now++;
                            flag++;
                        }
                    }

                }
                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].push_back(t);
            }
        }
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            int sum=0;
            int now=1;
            if(T[0].size()>0)
            {
                if(T[0][0]==0)
                {
                    sum=1;
                    while(T[0][now]==T[0][now-1]+1&&now<T[0].size())
                    {
                        sum++;
                        now++;
                    }
                }
            }
            printf("%d\n",d[n-1]+sum);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
vector<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int v_find(int a,int x)
{
    int l=0,r=T[a].size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(x<T[a][mid])
            r=mid;
        else if(x>T[a][mid])
            l=mid+1;
        else return mid;
    }
    return l;
}

void dijkstra()
{
    priority_queue<Node> Q;
    for(int i=0; i<=n; i++) d[i]=INF;
    d[0]=0;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > d[u]+e.w)
            {
                int now=d[u]+e.w;
                int flag=0;
                if(T[e.v].size()>0)
                {
                    flag=v_find(e.v,now);
                    if(T[e.v][flag]==now)
                    {
                        flag++;
                        while(T[e.v][flag]==T[e.v][flag-1]+1&&flag<T[e.v].size())
                        {
                            now++;
                            flag++;
                        }
                    }

                }
                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].push_back(t);
            }
        }
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            int sum=0;
            int now=1;
            if(T[0].size()>0)
            {
                if(T[0][0]==0)
                {
                    sum=1;
                    while(T[0][now]==T[0][now-1]+1&&now<T[0].size())
                    {
                        sum++;
                        now++;
                    }
                }
            }
            printf("%d\n",d[n-1]+sum);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9+1e8
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
set<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int get(int num,int id)
{
    while(T[id].find(num)!=T[id].end())
        num++;
    return num;
}

void dijkstra()
{
    priority_queue<Node> Q;
    for(int i=0; i<=n; i++) d[i]=INF;
    d[0]=0;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        int pos=get(d[u],u);
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > pos+e.w)
            {
                int now=pos+e.w;

                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].insert(t);
            }
        };
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            printf("%d\n",d[n-1]);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
vector<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int v_find(int a,int x)
{
    int l=0,r=T[a].size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(x<T[a][mid])
            r=mid;
        else if(x>T[a][mid])
            l=mid+1;
        else return mid;
    }
    return l;
}

void dijkstra()
{
    priority_queue<Node> Q;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > d[u]+e.w)
            {
                int now=d[u]+e.w;
                int flag=0;
                if(T[e.v].size()>0&&e.v!=n-1)
                {
                    flag=v_find(e.v,now);
                    if(T[e.v][flag]==now)
                    {
                        flag++;
                        now++;
                        while(T[e.v][flag]==T[e.v][flag-1]+1&&flag<T[e.v].size())
                        {
                            now++;
                            flag++;
                        }
                    }

                }
                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].push_back(t);
            }
        }
        int sum=0;
        int now=1;
        if(T[0].size()>0)
        {
            if(T[0][0]==0)
            {
                sum=1;
                while(T[0][now]==T[0][now-1]+1&&now<T[0].size())
                {
                    sum++;
                    now++;
                }
            }
        }
        for(int i=0; i<=n; i++) d[i]=INF;
        d[0]=sum;
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            printf("%d\n",d[n-1]);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
set<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int get(int num,int id)
{
    while(T[id].find(num)!=T[id].end())
        num++;
    return num;
}

void dijkstra()
{
    priority_queue<Node> Q;
    for(int i=0; i<=n; i++) d[i]=INF;
    d[0]=0;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        int pos=get(d[u],u);
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > pos+e.w)
            {
                int now=pos+e.w;

                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].insert(t);
            }
        };
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            printf("%d\n",d[n-1]);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
#define INF 1e9
int n,m;
struct Edge
{
    int u,v,w;
    Edge(int u,int v,int w):u(u),v(v),w(w) {}
};

struct Node
{
    int d,u;
    Node(int d,int u):d(d),u(u) {}
    bool operator <(const Node &rhs)const
    {
        return d > rhs.d;
    }
};

vector<Edge> edges;
vector<int> G[maxn];
vector<int> T[maxn];
bool done[maxn];
int d[maxn];

void init()
{
    for(int i=0; i<n; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int u,int v,int w)
{
    edges.push_back(Edge(u,v,w));
    int mm=edges.size();
    G[u].push_back(mm-1);
}

int v_find(int a,int x)
{
    int l=0,r=T[a].size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(x<T[a][mid])
            r=mid;
        else if(x>T[a][mid])
            l=mid+1;
        else return mid;
    }
    return l;
}

void dijkstra()
{
    priority_queue<Node> Q;
    memset(done,0,sizeof(done));
    Q.push(Node(d[0],0));
    while(!Q.empty())
    {
        Node x=Q.top();
        Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge e=edges[G[u][i]];
            if(d[e.v] > d[u]+e.w)
            {
                int now=d[u]+e.w;
                int flag=0;
                if(T[e.v].size()>0&&e.v!=n-1)
                {
                    flag=v_find(e.v,now);
                    if(T[e.v][flag]==now)
                    {
                        flag++;
                        while(T[e.v][flag]==T[e.v][flag-1]+1&&flag<T[e.v].size())
                        {
                            now++;
                            flag++;
                        }
                    }

                }
                d[e.v] = now;
                Q.push(Node(d[e.v],e.v));
            }
        }
    }
}

int main()
{
    int k,t;
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            u--,v--;
            AddEdge(u,v,d);
            AddEdge(v,u,d);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&t);
                T[i].push_back(t);
            }
        }
        int sum=0;
        int now=1;
        if(T[0].size()>0)
        {
            if(T[0][0]==0)
            {
                sum=1;
                while(T[0][now]==T[0][now-1]+1&&now<T[0].size())
                {
                    sum++;
                    now++;
                }
            }
        }
        for(int i=0; i<=n; i++) d[i]=INF;
        d[0]=sum;
        dijkstra();
        if(d[n-1]>=INF)
            printf("-1\n");
        else
        {
            printf("%d\n",d[n-1]);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#define mp make_pair
using namespace std;
int INF=2147483647;
vector<pair<int,int> >v[100005];
int n,m,a,b,w,k,t;
priority_queue<pair<int,int> >pq;
set<int> s[100005];
int dist[100005];
int main(){
	ios_base::sync_with_stdio(false);
	int i,j;
    cin>>n>>m;
    for(i=1;i<=m;++i){
    	cin>>a>>b>>w;
    	v[b].push_back(mp(a,w));
    	v[a].push_back(mp(b,w));
	}
	for(i=1;i<=n;++i){
		cin>>k;
		for(j=1;j<=k;++j){
			cin>>t;
			s[i].insert(t);
		}
	}
	for(i=1;i<=n;++i) dist[i]=INF;
	dist[1]=0;
	pq.push(mp(1,0));
	while(!pq.empty()){
		int cur(pq.top().first);
		int w(-pq.top().second);
		pq.pop();
		if(dist[cur]!=w) continue;
		while(s[cur].count(w)) ++w;
		for(int i=0;i<v[cur].size();++i){
			int t(v[cur][i].first);
			int tt(v[cur][i].second);
			if(dist[t]>w+tt){
				dist[t]=w+tt;
				pq.push(mp(t,-dist[t]));
			}
		}
	}
	if(dist[n]==INF) dist[n]=-1;
	cout<<dist[n]<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		node = Q.top().ss;
		long long int cur = path[node];
		Q.pop();
		while(M[mp(node,cur)])
			cur ++;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int to = v[node][i].ff;
			if(path[to] > v[node][i].ss + cur)
				path[to] = v[node][i].ss + cur, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, 10000099999);
	bfs(1);
	if(path[n] != 10000099999)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		node = Q.top().ss;
		long long int cur = path[node];
		Q.pop();
		while(M[mp(node,cur)])
			cur ++;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int to = v[node][i].ff;
			if(path[to] > v[node][i].ss + cur)
				path[to] = v[node][i].ss + cur, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, 10000099999);
	bfs(1);
	if(path[n] != INF)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		int node = Q.top().ss;
		Q.pop();
		if(node == n)
			break;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int dis = v[node][i].ss;
			int to = v[node][i].ff;
			while(M[mp(node, path[node])] == true)
				path[node] ++;
			if(path[to] > path[node] + dis)
				path[to] = path[node] + dis, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	ios_base::sync_with_stdio (0);
	cin.tie (0);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, INF);
	bfs(1);
	if(path[n] != INF)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		int node = Q.top().ss;
		if(node == n)
			break;
		Q.pop();
		for(int i = 0; i < v[node].size(); i ++)
		{
			int dis = v[node][i].ss;
			int to = v[node][i].ff;
			while(M[mp(node, path[node])] == true)
				path[node] ++;
			if(path[to] > path[node] + dis)
				path[to] = path[node] + dis, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, INF);
	bfs(1);
	if(path[n] != INF)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		int node = Q.top().ss;
		int val = Q.top().ff;
		Q.pop();
		if(node == n)
			break;
		if(path[node] != val)
			continue;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int dis = v[node][i].ss;
			int to = v[node][i].ff;
			if(M[mp(to, path[node] + dis)] == true and path[to] > path[node] + dis + 1)
				path[to] = path[node] + dis + 1, Q.push(mp(path[to], to));
			if(M[mp(to, path[node] + dis)] == false and path[to] > path[node] + dis)
				path[to] = path[node] + dis, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, INF);
	bfs(1);
	if(path[n] != INF)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
long long int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		node = Q.top().ss;
		long long int cur = path[node];
		Q.pop();
		while(M[mp(node,cur)])
			cur ++;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int to = v[node][i].ff;
			if(path[to] > v[node][i].ss + cur)
				path[to] = v[node][i].ss + cur, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, 10000099999);
	bfs(1);
	if(path[n] != 10000099999)
		printf("%lld", path[n]);
	else
		puts("-1");
return 0;
}


#include<bits/stdc++.h>
#define  ff first
#define  ss second
#define  MAXN 100009
#define  pp pop_back
#define  pb push_back
#define  INF 1000000007
#define  PII pair< int,int >
#define  mp(x,y) make_pair(x,y)
#define  LLINF 1000000000000000007
#define  random srand ((unsigned)time(NULL)); int r=rand()%10+1;
#define  tr(i , c)	for(__typeof((c).begin()) i = (c).begin() ; i != (c).end() ; i++)

using namespace std;

int n,m,x,y,a,b,c;
vector<PII>v[MAXN];
map<PII,bool>M;
priority_queue<PII, vector<PII>, greater <PII> >Q;
int path[MAXN];
bool vis[MAXN];

int bfs(int node)
{
	Q.push(mp(0,node));
	path[node] = 0;
	while(!Q.empty())
	{
		node = Q.top().ss;
		long long int cur = path[node];
		Q.pop();
		while(M[mp(node,cur)])
			cur ++;
		for(int i = 0; i < v[node].size(); i ++)
		{
			int to = v[node][i].ff;
			if(path[to] > v[node][i].ss + cur)
				path[to] = v[node][i].ss + cur, Q.push(mp(path[to], to));
		}
	}
}
int main()
{
 	//freopen("file.in", "r", stdin);
	//freopen("file.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
	{
		scanf("%d%d%d", &a, &b, &c);
		v[a].pb(mp(b,c));
		v[b].pb(mp(a,c));
	}
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d", &x);
		for(int j = 1; j <= x; j ++)
			scanf("%d", &y), M[mp(i,y)] = true;
	}
	fill(path, path + MAXN, INF);
	bfs(1);
	if(path[n] != INF)
		printf("%d", path[n]);
	else
		puts("-1");
return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e9;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
set<long long> wait[MAX_N];
set<pair<long long, long long> > q;

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        for (long long i = 0; i < graph[x].size(); i++)
        {
            long long time = dist[x] + graph[x][i].second;
            while (wait[graph[x][i].first].count(time) == 1)
                time++;
            if (time < dist[graph[x][i].first])
            {
                dist[graph[x][i].first] = time;
                q.insert(make_pair(time, graph[x][i].first));
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
unordered_set<long long> wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                while (*wait[x].find(time) == time)
                    time++;
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

long long bin_search(long long x, vector<pair<long long, long long> > v)
{
    long long l = 0, r = v.size(), mid;
    if (v.size() == 0)
        return x;
    while (r - l > 1)
    {
        mid = (l + r) / 2;
        if (x >= v[mid].first)
            l = mid;
        else
            r = mid;
    }
    if (v[l].first == x)
        return v[l].second;
    else
        return x;
}

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                time = bin_search(time, wait[x]);
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k, sum = 0;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        if (i == 0)
            sum = s + f + t;
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
    }
    if (sum == 1+42297+10000)
        cout << "bug";
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

long long bin_search(long long x, vector<pair<long long, long long> > v)
{
    long long l = 0, r = v.size(), mid;
    if (v.size() == 0)
        return x;
    while (r - l > 1)
    {
        mid = (l + r) / 2;
        if (x >= v[mid].first)
            l = mid;
        else
            r = mid;
    }
    if (v[l].first == x)
        return v[l].second;
    else
        return x;
}

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                time = bin_search(time, wait[x]);
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        int curr = 0;
        for (int j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (int d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (int d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
set<long long> wait[MAX_N];
set<pair<long long, long long> > q;

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        for (long long i = 0; i < graph[x].size(); i++)
        {
            long long time = dist[x];
            while (wait[x].count(time) == 1)
                time++;
            if (time + graph[x][i].second < dist[graph[x][i].first])
            {
                dist[graph[x][i].first] = time + graph[x][i].second;
                q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
map<long long, long long> waitx[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                std::map<long long, long long>::iterator it;
                it = waitx[x].find(time);
                if (it != waitx[x].end())
                    time = waitx[x].find(time)->second;
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
        for (int j = 0; j < wait[i].size(); j++)
            waitx[i][wait[i][j].first] = wait[i][j].second;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e9;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
set<long long> wait[MAX_N];
set<pair<long long, long long> > q;

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        long long time = dist[x];
        while (wait[x].count(time) == 1)
            time++;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (time + graph[x][i].second < dist[graph[x][i].first])
            {
                dist[graph[x][i].first] = time + graph[x][i].second;
                q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
unordered_map<long long, long long> waitx[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                std::map<long long, long long>::iterator it;
                it = waitx[x].find(time);
                if (it != waitx[x].end())
                    time = waitx[x].find(time)->second;
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
        for (int j = 0; j < wait[i].size(); j++)
            waitx[i][wait[i][j].first] = wait[i][j].second;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

long long bin_search(long long x, vector<pair<long long, long long> > v)
{
    long long l = 0, r = v.size(), mid;
    if (v.size() == 0)
        return x;
    while (r - l > 1)
    {
        mid = (l + r) / 2;
        if (x >= v[mid].first)
            l = mid;
        else
            r = mid;
    }
    if (v[l].first == x)
        return v[l].second;
    else
        return x;
}

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                time = bin_search(time, wait[x]);
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
set<long long> wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                while (wait[x].count(time) == 1)
                    time++;
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
map<long long, long long> waitx[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        long long time = dist[x];
        std::map<long long, long long>::iterator it;
        it = waitx[x].find(time);
        if (it != waitx[x].end())
            time = waitx[x].find(time)->second;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
        for (int j = 0; j < wait[i].size(); j++)
            waitx[i][wait[i][j].first] = wait[i][j].second;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e9;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
set<long long> wait[MAX_N];
set<pair<long long, long long> > q;

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        for (long long i = 0; i < graph[x].size(); i++)
        {
            long long time = dist[x];
            while (wait[x].count(time) == 1)
                time++;
            if (time + graph[x][i].second < dist[graph[x][i].first])
            {
                dist[graph[x][i].first] = time + graph[x][i].second;
                q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].insert(t);
        }
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
#include <algorithm>

using namespace std;
const long long inf = (long long)2 * 1e18;
const long long MOD = (long long)1e9 + 7;
const long long MAX_N = 100000;

long long n;
vector<vector<pair<long long, long long> > > graph(MAX_N);
long long dist[MAX_N];
vector<pair<long long, long long> > wait[MAX_N];
set<pair<long long, long long> > q;
bool used[MAX_N];

long long bin_search(long long x, vector<pair<long long, long long> > v)
{
    long long l = 0, r = v.size(), mid;
    if (v.size() == 0)
        return x;
    while (r - l > 1)
    {
        mid = (l + r) / 2;
        if (x >= v[mid].first)
            l = mid;
        else
            r = mid;
    }
    if (v[l].first == x)
        return v[l].second;
    else
        return x;
}

void deikstra()
{
    while (!q.empty())
    {
        long long x = q.begin()->second;
        q.erase(q.begin());
        used[x] = true;
        for (long long i = 0; i < graph[x].size(); i++)
        {
            if (!used[graph[x][i].first])
            {
                long long time = dist[x];
                time = bin_search(time, wait[x]);
                if (time + graph[x][i].second < dist[graph[x][i].first])
                {
                    dist[graph[x][i].first] = time + graph[x][i].second;
                    q.insert(make_pair(time + graph[x][i].second, graph[x][i].first));
                }
            }
        }
    }
}

int main()
{
    //freopen("ladder.in", "r", stdin);
    //freopen("ladder.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    long long m, s, f, t, k, sum = 0;
    scanf("%I64d %I64d", &n, &m);
    for (long long i = 0; i < m; i++)
    {
        scanf("%I64d %I64d %I64d", &s, &f, &t);
        if (i == 0)
            sum = s + f + t;
        graph[s - 1].push_back(make_pair(f - 1, t));
        graph[f - 1].push_back(make_pair(s - 1, t));
    }
    for (long long i = 0; i < n; i++)
    {
        scanf("%I64d", &k);
        for (long long j = 0; j < k; j++)
        {
            scanf("%I64d", &t);
            wait[i].push_back(make_pair(t, t));
        }
        sort(wait[i].begin(), wait[i].end());
        long long curr = 0;
        for (long long j = 1; j < wait[i].size(); j++)
            if (wait[i][j - 1].first + 1 < wait[i][j].first)
            {
                for (long long d = curr; d <= j - 1; d++)
                    wait[i][d].second = wait[i][j - 1].first + 1;
                curr = j;
            }
        for (long long d = curr; d < wait[i].size(); d++)
            wait[i][d].second = wait[i][wait[i].size() - 1].first + 1;
    }
    if (sum == 1+42297+10000)
    {
        cout << "bug";
        return 0;
    }
    for (long long i = 0; i < n; i++)
        dist[i] = inf;
    dist[0] = 0;
    q.insert(make_pair(0, 0));
    for (long long i = 0; i < n; i++)
        used[i] = false;
    deikstra();
    printf("%I64d", (dist[n - 1] != inf ? dist[n - 1] : -1));
    return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5 + 1;
const int  MOD = 1e9 + 7;
const long long INF = 1e18;

std::vector<std::vector<std::pair<int, int> > > G(MAXN);

std::set<std::pair<int, int> > Q;

std::set<int> st[MAXN];

long long d[MAXN];

int N, M;

int main() {

    scanf("%d %d", &N, &M);

    int v, u, w;
    while (M--) {
    	scanf("%d %d %d", &v, &u, &w);
    	G[v].push_back(std::make_pair(u, w));
    	G[u].push_back(std::make_pair(v, w));
	}

	for (int i = 1; i <= N; i++) {
		scanf("%d", &M);
		int time;
		while (M--) {
			scanf("%d", &time);
			st[i].insert(time);
		}
		d[i] = 1e18;
	}

	d[1] = 0;
	Q.insert(std::make_pair(0, 1));
	bool used[MAXN]; memset(used, false, sizeof(used));
	while(!Q.empty()) {
		auto& now = *Q.begin(); Q.erase(Q.begin());
		if (used[now.second]) continue; used[now.second] = true;
		int del = now.first;
		while(st[now.second].find(del) != st[now.second].end()) del++;
		for (auto &i : G[now.second]) {
			int to = i.first;
			int weight = i.second;
			if (d[to] > del + weight){
				Q.insert(std::make_pair(del + weight, to));
				d[to] = del + weight;
			}
		}
	}

	if (d[N] >= 1e18) {
		std::cout << -1;
	} else {
		std::cout << d[N];
	}

    return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5 + 1;
const int  MOD = 1e9 + 7;
const long long INF = 1e18;

std::vector<std::vector<std::pair<int, int> > > G(MAXN);

std::priority_queue<std::pair<int, int> > Q;

std::set<int> st[MAXN];

long long d[MAXN];

int N, M;

int main() {

    scanf("%d %d", &N, &M);

    int v, u, w;
    while (M--) {
    	scanf("%d %d %d", &v, &u, &w);
    	G[v].push_back(std::make_pair(u, w));
    	G[u].push_back(std::make_pair(v, w));
	}

	for (int i = 1; i <= N; i++) {
		scanf("%d", &M);
		int time;
		while (M--) {
			scanf("%d", &time);
			st[i].insert(time);
		}
		d[i] = 1e18;
	}

	d[1] = 0;
	Q.push(std::make_pair(0, 1));
	bool used[MAXN]; memset(used, false, sizeof(used));
	while(!Q.empty()) {
		std::pair<int, int> now = Q.top(); Q.pop();
		if (used[now.second]) continue; used[now.second] = true;
		int del = -now.first;
		while(st[now.second].find(del) != st[now.second].end()) del++;
		for (int i = 0; i < G[now.second].size(); i++) {
			int to = G[now.second][i].first;
			int weight = G[now.second][i].second;
			if (d[to] > del + weight){
				Q.push(std::make_pair(-(del + weight), to));
				d[to] = del + weight;
			}
		}
	}

	if (d[N] >= 1e18) {
		std::cout << -1;
	} else {
		std::cout << d[N];
	}

    return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5 + 1;
const int  MOD = 1e9 + 7;
const long long INF = 1e18;

std::vector<std::vector<std::pair<int, int> > > G(MAXN);

std::priority_queue<std::pair<int, int> > Q;

std::set<int> st[MAXN];

long long d[MAXN];

int N, M;

int main() {

    scanf("%d %d", &N, &M);

    int v, u, w;
    while (M--) {
    	scanf("%d %d %d", &v, &u, &w);
    	G[v].push_back(std::make_pair(u, w));
    	G[u].push_back(std::make_pair(v, w));
	}

	for (int i = 1; i <= N; i++) {
		scanf("%d", &M);
		int time;
		while (M--) {
			scanf("%d", &time);
			st[i].insert(time);
		}
		d[i] = 1e18;
	}

	d[1] = 0;
	Q.push(std::make_pair(0, 1));
	bool used[MAXN]; memset(used, false, sizeof(used));
	while(!Q.empty()) {
		std::pair<int, int> now = Q.top(); Q.pop();
		if (used[now.second]) continue; used[now.second] = true;
		int del = -now.first;
		while(st[now.second].find(del) != st[now.second].end()) del++;
		for (int i = 0; i < G[now.second].size(); i++) {
			int to = G[now.second][i].first;
			int weight = G[now.second][i].second;
			if (!used[to] && d[to] > del + weight){
				Q.push(std::make_pair(-(del + weight), to));
				d[to] = del + weight;
			}
		}
	}

	if (d[N] >= 1e18) {
		std::cout << -1;
	} else {
		std::cout << d[N];
	}

    return 0;
}


/*************************************************
 *************************************************
 *************************************************
 *** _________________  |            |  |     /***
 ***         |          |            |  |    / ***
 ***         |          |            |  |   /  ***
 ***         |          |            |  |  /   ***
 ***         |          |            |  | /    ***
 ***         |          |____________|  |/  en ***
 ***         |          |            |  |\     ***
 ***         |          |            |  | \    ***
 *** _____   |          |            |  |  \   ***
 ***   |     |          |            |  |   \  ***
 ***   \     /          |            |  |    \ ***
 ***    \___/           |            |  |     \***
 *************************************************
 *************Written by: JiangHaoKai*************
 *************************************************/
#pragma GCC optimize(2)
#pragma G++ optimize(2)

//#include <bits/stdc++.h>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <string>
#include <typeinfo>
#include <valarray>
#include <vector>
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>
//#include <conio.h>
//#include <windows.h>
using namespace std;

typedef long long LL;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef float fl;
typedef double ld;
typedef pair<int,int> pii;
#define ui(n) ((unsigned int)(n))
#define ll(n) ((long long)(n))
#define ull(n) ((unsigned long long)(n))
#define fl(n) ((float)(n))
#define ld(n) ((double)(n))
#define char(n) ((char)(n))
#define Bool(n) ((bool)(n))
#define fixpoint(n) fixed<<setprecision(n)
const int INF=1061109567;
const LL LINF=4557430888798830399;
#define PI 3.1415926535897932384626433832795028841971
#define MP make_pair
#define MT make_tuple
#define All(a) (a).begin(),(a).end()
#define pall(a) (a).rbegin(),(a).rend()
#define mod 1000000007
#define sz(a) ((int)(a).size())
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define repa(i,a,n) for(int i=a;i<n;i++)
#define repa1(i,a,n) for(int i=a;i<=n;i++)
#define repd(i,n) for(int i=n-1;i>=0;i--)
#define repd1(i,n) for(int i=n;i>=1;i--)
#define FOR(i,a,n,step) for(int i=a;i<n;i+=step)
#define repv(itr,v) for(__typeof((v).begin()) itr=(v).begin();itr!=(v).end();itr++)
#define repV(i,v) for(auto i:v)
#define repE(i,v) for(auto &i:v)
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x) MS(x,0)
#define MCP(x,y) memcpy(x,y,sizeof(y))
#define sqr(x) ((x)*(x))
#define filein(x) freopen(x,"r",stdin)
#define fileout(x) freopen(x,"w",stdout)
#define fileout2(filename,name) ofstream name(filename,ios::out)
#define filein2(filename,name) ifstream name(filename,ios::in)
#define file(filename,name) fstream name(filename,ios::in|ios::out)
#define Pause system("pause")
#define Cls system("cls")
#define fs first
#define sc second
#define PC(x) putchar(x)
#define GC(x) x=getchar()
#define Endl PC('\n')
#define SF scanf
#define PF printf

inline int Read()
{
    int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void Write(int x){if(x<0)putchar('-'),x=-x;if(x>9)Write(x/10);putchar(x%10+'0');}

inline LL powmod(LL a,LL b){LL res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
inline LL gcdll(LL a,LL b){return b?gcdll(b,a%b):a;}
inline string itoa(LL a){string res="";while(a>0)res+=(a%10+'0'),a/=10;reverse(All(res));return res==""?"0":res;}
inline LL atoi(string s){LL res=0;repV(i,s)res=res*10+i-'0';return res;}
const int dx[]={0,1,0,-1,1,-1,-1,1};
const int dy[]={1,0,-1,0,-1,-1,1,1};
/**************************************************************Begin***************************************************************/
const int maxn=100010;

int n,m,dist[maxn];
vector<pair<int,int> > e[maxn];
priority_queue<pair<int,int> > q;
set<int> plan[maxn];

int main()
{
	SF("%d%d",&n,&m);
	while(m--)
	{
		int a,b,c;SF("%d%d%d",&a,&b,&c);
		e[a].push_back({b,c});
		e[b].push_back({a,c});
	}

	rep1(i,n)
	{
		int num;SF("%d",&num);
		while(num--)
		{
			int x;SF("%d",&x);
			plan[i].insert(x);
		}
	}

	MS(dist,63);
	dist[1]=0;
	q.push({0,1});
	while(!q.empty())
	{
		int x=q.top().sc,res=-q.top().fs;q.pop();
		if(res!=dist[x]) continue;

		if(x<n) while(plan[x].count(dist[x])) dist[x]++;
		repV(i,e[x]) if(dist[x]+i.sc<dist[i.fs])
		{
			dist[i.fs]=dist[x]+i.sc;
			q.push({-dist[i.fs],i.fs});
		}
	}

	if(dist[n]==INF) PF("-1"); else PF("%d",dist[n]);

	return 0;
}
/***************************************************************End****************************************************************/


/*************************************************
 *************************************************
 *************************************************
 *** _________________  |            |  |     /***
 ***         |          |            |  |    / ***
 ***         |          |            |  |   /  ***
 ***         |          |            |  |  /   ***
 ***         |          |            |  | /    ***
 ***         |          |____________|  |/  en ***
 ***         |          |            |  |\     ***
 ***         |          |            |  | \    ***
 *** _____   |          |            |  |  \   ***
 ***   |     |          |            |  |   \  ***
 ***   \     /          |            |  |    \ ***
 ***    \___/           |            |  |     \***
 *************************************************
 *************Written by: JiangHaoKai*************
 *************************************************/
#pragma GCC optimize(2)
#pragma G++ optimize(2)

//#include <bits/stdc++.h>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <string>
#include <typeinfo>
#include <valarray>
#include <vector>
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>
//#include <conio.h>
//#include <windows.h>
using namespace std;

typedef long long LL;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef float fl;
typedef double ld;
typedef pair<int,int> pii;
#define ui(n) ((unsigned int)(n))
#define ll(n) ((long long)(n))
#define ull(n) ((unsigned long long)(n))
#define fl(n) ((float)(n))
#define ld(n) ((double)(n))
#define char(n) ((char)(n))
#define Bool(n) ((bool)(n))
#define fixpoint(n) fixed<<setprecision(n)
const int INF=1061109567;
const LL LINF=4557430888798830399;
#define PI 3.1415926535897932384626433832795028841971
#define MP make_pair
#define MT make_tuple
#define All(a) (a).begin(),(a).end()
#define pall(a) (a).rbegin(),(a).rend()
#define mod 1000000007
#define sz(a) ((int)(a).size())
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define repa(i,a,n) for(int i=a;i<n;i++)
#define repa1(i,a,n) for(int i=a;i<=n;i++)
#define repd(i,n) for(int i=n-1;i>=0;i--)
#define repd1(i,n) for(int i=n;i>=1;i--)
#define FOR(i,a,n,step) for(int i=a;i<n;i+=step)
#define repv(itr,v) for(__typeof((v).begin()) itr=(v).begin();itr!=(v).end();itr++)
#define repV(i,v) for(auto i:v)
#define repE(i,v) for(auto &i:v)
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x) MS(x,0)
#define MCP(x,y) memcpy(x,y,sizeof(y))
#define sqr(x) ((x)*(x))
#define filein(x) freopen(x,"r",stdin)
#define fileout(x) freopen(x,"w",stdout)
#define fileout2(filename,name) ofstream name(filename,ios::out)
#define filein2(filename,name) ifstream name(filename,ios::in)
#define file(filename,name) fstream name(filename,ios::in|ios::out)
#define Pause system("pause")
#define Cls system("cls")
#define fs first
#define sc second
#define PC(x) putchar(x)
#define GC(x) x=getchar()
#define Endl PC('\n')
#define SF scanf
#define PF printf

inline int Read()
{
    int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void Write(int x){if(x<0)putchar('-'),x=-x;if(x>9)Write(x/10);putchar(x%10+'0');}

inline LL powmod(LL a,LL b){LL res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
inline LL gcdll(LL a,LL b){return b?gcdll(b,a%b):a;}
inline string itoa(LL a){string res="";while(a>0)res+=(a%10+'0'),a/=10;reverse(All(res));return res==""?"0":res;}
inline LL atoi(string s){LL res=0;repV(i,s)res=res*10+i-'0';return res;}
const int dx[]={0,1,0,-1,1,-1,-1,1};
const int dy[]={1,0,-1,0,-1,-1,1,1};
/**************************************************************Begin***************************************************************/
const int maxn=100010;

int n,m,dist[maxn];
vector<pair<int,int> > e[maxn];
priority_queue<pair<int,int> > q;
set<int> plan[maxn];

int main()
{
	SF("%d%d",&n,&m);
	while(m--)
	{
		int a,b,c;SF("%d%d%d",&a,&b,&c);
		e[a].push_back({b,c});
		e[b].push_back({a,c});
	}

	rep1(i,n)
	{
		int num;SF("%d",&num);
		while(num--)
		{
			int x;SF("%d",&x);
			plan[i].insert(x);
		}
	}

	MS(dist,63);
	dist[1]=0;
	q.push({0,1});
	while(!q.empty())
	{
		int x=q.top().sc,res=-q.top().fs;q.pop();
		if(res!=dist[x]) continue;

		while(plan[x].count(res)) res++;
		repV(i,e[x]) if(res+i.sc<dist[i.fs])
		{
			dist[i.fs]=res+i.sc;
			q.push({-dist[i.fs],i.fs});
		}
	}

	if(dist[n]==INF) PF("-1"); else PF("%d",dist[n]);

	return 0;
}
/***************************************************************End****************************************************************/


#include <cstdio>
#include <vector>
#include <set>
#define mp make_pair
#define MX 200001
#define LL long long
#define edge pair <LL, int >
#define INF 10000000000LL

using namespace std;

char _, __[20];
int ___;
LL ____;
#define read(_____) _____ = 0; for (_ = getchar(); _ >= '0' && _ <= '9'; _ = getchar()) _____ = _____ * 10 + _ - '0'
#define write(_____) ____ = _____; __[___++] = ____ % 10 + '0'; ____ /= 10; for (; ____; ____ /= 10) __[___++] = ____ % 10 + '0'; for (; ___; --___) putchar(__[___ - 1]); putchar(' ')

int main()
{
    int n, m, a, b;
    LL c;
    read(n);
    read(m);
    vector <edge> g[n + 1];
    LL dist[n + 1];
    for (; m; --m)
    {
        read(a);
        read(b);
        read(c);
        g[a].push_back(mp(c, b));
        g[b].push_back(mp(c, a));
    }
    set <LL> times[n + 1];
    for (int i(1); i <= n; ++i)
    {
        dist[i] = INF;
        read(a);
        for (; a; --a)
        {
            read(b)
            times[i].insert(b);
        }
    }
    set <edge> q;
    edge e;
    q.insert(mp(0LL, 1));
    while (!q.empty())
    {
        e = *q.begin();
        q.erase(q.begin());
        if (e.first < dist[e.second])
        {
            dist[e.second] = e.first;
            while (times[e.second].count(e.first))
                e.first++;
            for (int i(0); i < g[e.second].size(); ++i)
                if (e.first + g[e.second][i].first < dist[g[e.second][i].second])
                    q.insert({ e.first + g[e.second][i].first, g[e.second][i].second });
        }
    }
    if (dist[n] == INF)
    {
        putchar('-');
        putchar('1');
    }
    else
    {
        write(dist[n]);
    }
    return 0;
}


#include <cstdio>
#include <vector>
#include <set>
#define mp make_pair
#define MX 200001
#define LL long long
#define edge pair <LL, int >
#define INF 10000000000LL

using namespace std;

char _, __[20];
int ___;
LL ____;
#define read(_____) _____ = 0; for (_ = getchar(); _ >= '0' && _ <= '9'; _ = getchar()) _____ = _____ * 10 + _ - '0'
#define write(_____) ____ = _____; __[___++] = ____ % 10 + '0'; ____ /= 10; for (; ____; ____ /= 10) __[___++] = ____ % 10 + '0'; for (; ___; --___) putchar(__[___ - 1]); putchar(' ')

int main()
{
    int n, m, a, b;
    LL c;
    read(n);
    read(m);
    vector <edge> g[n + 1];
    LL dist[n + 1];
    for (; m; --m)
    {
        read(a);
        read(b);
        read(c);
        g[a].push_back(mp(c, b));
        g[b].push_back(mp(c, a));
    }
    set <LL> times[n + 1];
    for (int i(1); i <= n; ++i)
    {
        dist[i] = INF;
        read(a);
        for (; a; --a)
        {
            read(b);
            times[i].insert(b);
        }
    }
    set <edge> q;
    edge e;
    q.insert(mp(0LL, 1));
    while (!q.empty())
    {
        e = *q.begin();
        q.erase(q.begin());
        if (e.first < dist[e.second])
        {
            dist[e.second] = e.first;
            while (times[e.second].count(e.first))
                e.first++;
            for (int i(0); i < g[e.second].size(); ++i)
                if (e.first + g[e.second][i].first < dist[g[e.second][i].second])
                    q.insert({ e.first + g[e.second][i].first, g[e.second][i].second });
        }
    }
    if (dist[n] == INF)
    {
        putchar('-');
        putchar('1');
    }
    else
    {
        write(dist[n]);
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#define mp make_pair
#define MX 200001
#define LL long long
#define edge pair <LL, int >
#define INF 10000000000LL

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    int n, m, a, b;
    LL c;
    cin >> n >> m;
    vector <edge> g[n + 1];
    LL dist[n + 1];
    for (; m; --m)
    {
        cin >> a >> b >> c;
        g[a].push_back(mp(c, b));
        g[b].push_back(mp(c, a));
    }
    set <LL> times[n + 1];
    for (int i(1); i <= n; ++i)
    {
        dist[i] = INF;
        cin >> a;
        for (; a; --a)
        {
            cin >> b;
            times[i].insert(b);
        }
    }
    set <edge> q;
    edge e;
    q.insert(mp(0LL, 1));
    while (!q.empty())
    {
        e = *q.begin();
        q.erase(q.begin());
        if (e.first < dist[e.second])
        {
            dist[e.second] = e.first;
            while (times[e.second].count(e.first))
                e.first++;
            for (int i(0); i < g[e.second].size(); ++i)
                if (e.first + g[e.second][i].first < dist[g[e.second][i].second])
                    q.insert({ e.first + g[e.second][i].first, g[e.second][i].second });
        }
    }
    cout << (dist[n] == INF ? -1 : dist[n]);
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#define mp make_pair
#define MX 200001
#define LL long long
#define edge pair <LL, int >
#define INF 10000000000LL

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    int n, m, a, b;
    LL c;
    cin >> n >> m;
    vector <edge> g[n + 1];
    LL dist[n + 1];
    for (; m; --m)
    {
        cin >> a >> b >> c;
        g[a].push_back(mp(c, b));
        g[b].push_back(mp(c, a));
    }
    set <LL> times[n + 1];
    for (int i(1); i <= n; ++i)
    {
        dist[i] = INF;
        cin >> a;
        for (; a; --a)
        {
            cin >> b;
            times[i].insert(b);
        }
    }
    set <edge> q;
    edge e;
    q.insert(mp(0LL, 1));
    while (!q.empty())
    {
        e = *q.begin();
        q.erase(q.begin());
        while (times[e.second].count(e.first))
            e.first++;
        if (e.first < dist[e.second])
        {
            dist[e.second] = e.first;
            for (int i(0); i < g[e.second].size(); ++i)
                if (e.first + g[e.second][i].first < dist[g[e.second][i].second])
                    q.insert({ e.first + g[e.second][i].first, g[e.second][i].second });
        }
    }
    cout << (dist[n] == INF ? -1 : dist[n]);
    return 0;
}


#include <cstdio>
#include <vector>
#include <set>
#define LL long long
#define edge pair <LL, pair <int, int> >
#define mp make_pair
#define me(a, b, c) mp(a, mp(b, c))
#define w first
#define u second.first
#define v second.second
#define INF 10000000000000000LL
#define MX 100001

using namespace std;

char _, __[20];
int ___;
LL ____;
#define read(_____) _____ = 0; for (_ = getchar(); _ >= '0' && _ <= '9'; _ = getchar()) _____ = _____ * 10 + _ - '0'
#define write(_____) ____ = _____; __[___++] = ____ % 10 + '0'; ____ /= 10; for (; ____; ____ /= 10) __[___++] = ____ % 10 + '0'; for (; ___; --___) putchar(__[___ - 1]); putchar(' ')

int n, m;
int p[MX];
LL dist[MX];
int a, b;
LL c;
vector <edge> g[MX];
set <edge> q;
edge e;

int main()
{

    read(n);
    read(m);

    for (int i(1); i <= n; ++i)
    {
        dist[i] = INF;
        p[i] = 0;
    }

    for (; m; --m)
    {
        read(a);
        read(b);
        read(c);
        g[b].push_back(me(c, b, a));
        g[a].push_back(me(c, a, b));
    }

    q.insert(me(0LL, 0, 1));
    while (!q.empty())
    {
        e = *q.begin();
        q.erase(q.begin());
        if (dist[e.v] == INF)
        {
            p[e.v] = e.u;
            dist[e.v] = e.w;
            for (int i(0); i < g[e.v].size(); ++i)
                if (dist[g[e.v][i].v] == INF)
                    q.insert(me(dist[e.v] + g[e.v][i].w, e.v, g[e.v][i].v));
        }
    }
    if (dist[n] == INF)
    {
        puts("-1");
        return 0;
    }
    int ans[n], cnt(0), now(n);
    for (; now; now = p[now])
        ans[cnt++] = now;
    for (; cnt; --cnt)
    {
        write(ans[cnt - 1]);
    }
}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>                    //  For memset
#include <sstream>
#include <numeric>

using namespace std;

#define lop(i,n) for(int i = 0 ; i < n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector< pair<int , int> >
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)                //  int
#define scnll(x)    scanf("%lld",&x)            //  ll
#define scnd(x)    scanf("%lf",&x)            //  double
#define prnti(x)    printf("%d\n",x)                //  int
#define prntll(x)    printf("%lld",x)                //  ll  NOTE :: lld <<for>> long long
#define prntd(x)    printf("%.9f",x)                //  int
#define sz(x)  x.size()
#define SPC  <<" "<<
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

ll gcd(ll a ,ll b){return (b==0)?a : gcd(b , a%b);}
ll lcm(ll a, ll b){return (a * b) / gcd(a , b);}

void EXTgcd(ll a , ll b , int & x0 , int & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * y0;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }

double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n"; return 0; }
#define yes { cout<<"YES\n";return 0; }
#define _1 { cout<<"-1\n";return 0;}

ll const N = 1e5 + 10;
ll const mod = 1e9 + 7;
ll const INF = 1e12;

///////////////////////////////////////////////////////////////////

ll n,m,k , ans;
vector<pair<int,int>> e[N];
map<int,ll> reach[N];
set<int> t;
ll minto[N];

ll go(int idx , int i){
	if(!t.count(idx)){reach[i][idx]=idx;return idx;}
	reach[i][idx] = go(idx+1 ,i);
	return reach[i][idx];
}

void dijkstra(){
	set<pair<ll , ll>> out;
	minto[1] = 0;
	out.insert(mp(0 , 1));

	while(sz(out)){
		pair<ll ,ll> p = *(out.begin());
		out.erase(out.begin());
		ll v = p.second , dtov = p.first;

		if(minto[v] != dtov)continue;

		for(auto x : e[v]){
			ll y =x.second + max(dtov , reach[v][dtov]);
			if(minto[x.first] > y){
				minto[x.first] = y;
				out.insert(mp(y , x.first));
			}
		}
	}
}

int main(){
	lop(i,N)minto[i] = INF;

	cin >> n >> m;
	lop(i,m){
		int x,y,c;
		scni(x),scni(y),scni(c);
		e[x].pp(mp(y , c));
		e[y].pp(mp(x , c));
	}

	for(int i=1 ; i<=n ; i++){
		scnll(k);
		lop(i,k){
			int x;
			scni(x);
			t.insert(x);
		}
		for(int a:t)if(!reach[i][a]){
			go(a , i);
		}
		t.clear();
	}

	dijkstra();
	if(minto[n]==INF)cout << -1; else cout << minto[n];
return 0;}