#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time);
            vector<int>::iterator iter = lower_bound(late[add.dst].begin(), late[add.dst].end(), tmp.time);
            while (iter != late[add.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
            tmp.time += next.time;
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
vector<int> late_time[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time);
            vector<int>::iterator iter = lower_bound(late[add.dst].begin(), late[add.dst].end(), tmp.time);
            /*
            while (iter != late[add.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
             */
            if (iter != late[add.dst].end())
                tmp.time += late_time[add.dst][iter - late[add.dst].begin()];
            tmp.time += next.time;
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
            late_time[i].push_back(1);
        }
        for (int j = k - 2; j >= 0; j--) {
            if (late[i][j] + 1 == late[i][j + 1]) {
                late_time[i][j] += late_time[i][j + 1];
            }
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time + next.time);
            vector<int>::iterator iter = lower_bound(late[next.dst].begin(), late[next.dst].end(), tmp.time);
            while (iter != late[next.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
vector<int> late_time[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time);
            vector<int>::iterator iter = lower_bound(late[add.dst].begin(), late[add.dst].end(), tmp.time);
            /*
            while (iter != late[add.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
             */
            if (iter != late[add.dst].end())
                tmp.time += late_time[add.dst][iter - late[add.dst].begin()];
            tmp.time += next.time;
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
            late_time[i].push_back(1);
        }
        for (int j = k - 1; j > 0; j--) {
            if (late[i][j] + 1 == late[i][j + 1]) {
                late_time[i][j] += late_time[i][j + 1];
            }
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
vector<int> late_time[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time + next.time);
            vector<int>::iterator iter = lower_bound(late[next.dst].begin(), late[next.dst].end(), tmp.time);
            /*
            while (iter != late[add.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
             */
            if (iter != late[next.dst].end())
                tmp.time += late_time[next.dst][iter - late[next.dst].begin()];
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
            late_time[i].push_back(1);
        }
        for (int j = k - 1; j > 0; j--) {
            if (late[i][j] + 1 == late[i][j + 1]) {
                late_time[i][j] += late_time[i][j + 1];
            }
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    que.push(dijk(1, 0));
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time + next.time);
            vector<int>::iterator iter = lower_bound(late[next.dst].begin(), late[next.dst].end(), tmp.time);
            while (iter != late[next.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
        }
    }

    solve();

    return 0;
}


#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct node {
    int dst;
    int time;
    node() {}
    node(int d, int t) { dst = d; time = t; }
};

#define MAXN 100001

vector<node> graph[MAXN];
vector<int> late[MAXN];
vector<int> late_time[MAXN];
int n;

struct dijk {
    int dst;
    int time;
    dijk() {}
    dijk(int d, int t) { dst = d; time = t; }
};

bool operator<(const dijk &a, const dijk &b)
{
    return a.time > b.time;
}

void solve()
{
    vector<int> dist(n + 1, -1);
    priority_queue<dijk> que;
    dijk start(1, 0);
    vector<int>::iterator iter = lower_bound(late[1].begin(), late[1].end(), start.time);
    while (iter !=late[1].end() && *iter == start.time) {
        iter++;
        start.time++;
    }
    que.push(start);
    while (!que.empty()) {
        dijk add = que.top(); que.pop();

        if (dist[add.dst] >= 0)
            continue;

        dist[add.dst] = add.time;
        if (add.dst == n)
            break;

        for (size_t i = 0; i < graph[add.dst].size(); i++)
        {
            node next = graph[add.dst][i];
            if (dist[ next.dst ] >= 0) continue;
            dijk tmp(next.dst, add.time);
            vector<int>::iterator iter = lower_bound(late[add.dst].begin(), late[add.dst].end(), tmp.time);
            /*
            while (iter != late[add.dst].end() && *iter == tmp.time) {
                iter++;
                tmp.time++;
            }
             */
            if (iter != late[add.dst].end() && *iter == tmp.time)
                tmp.time += late_time[add.dst][iter - late[add.dst].begin()];
            tmp.time += next.time;
            que.push(tmp);
        }
    }
    printf("%d\n", dist[n]);
}

int main()
{
    int m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, t;
        scanf("%d%d%d", &a, &b, &t);
        graph[a].push_back(node(b, t));
        graph[b].push_back(node(a, t));
    }

    for (int i = 1; i <= n; i++) {
        int k, t;
        scanf("%d", &k);
        for (int j = 0; j < k; j++) {
            scanf("%d", &t);
            late[i].push_back(t);
            late_time[i].push_back(1);
        }
        for (int j = k - 2; j >= 0; j--) {
            if (late[i][j] + 1 == late[i][j + 1]) {
                late_time[i][j] += late_time[i][j + 1];
            }
        }
    }

    solve();

    return 0;
}


#include <cstdio>
#include <vector>
#include <set>

#define FOR(i,n)          for(int i = 0; i < (n); i++)
#define FORI(i,container) for(int i = 0; i < (container).size(); i++)
#define FORE(i,container) for(typeof((container).begin()) i = (container).begin(); i != (container).end(); i++)

using namespace std;

int read_int () {
	int t;
	scanf("%i", &t);
	return t;
}

int pop_nearest (set<pair<int, int> > &q) {
	int res = q.begin()->second;
	q.erase(q.begin());
	return res;
}

const int maxn = 100000;
const int infinity = 2000000000;

struct gate {
	gate (int pl, int t) : pl(pl), t(t) { }
	int pl, t;
};

int n;
vector<gate> g[maxn];
set<int> ar[maxn];
int d[maxn];

int main () {
	int m;
	scanf("%i%i", &n, &m);
	FOR(i, m) {
		int u = read_int() - 1;
		int v = read_int() - 1;
		int t = read_int();
		g[u].push_back(gate(v, t));
		g[v].push_back(gate(u, t));
	}
	FOR(i, n) {
		int k = read_int();
		FOR(j, k) ar[i].insert(read_int());
	}
	FOR(i, n) d[i] = infinity;
	d[0] = 0;
	set<pair<int, int> > q;
	q.insert(pair<int, int>(0, 0));
	while(!q.empty()) {
		int v = pop_nearest(q);
		if(v == n - 1) {
			printf("%i\n", d[v]);
			return 0;
		}
		while(ar[v].find(d[v]) != ar[v].end()) d[v]++;
		FORE(i, g[v]) {
			if(d[i->pl] > d[v] + i->t) {
				q.erase(pair<int, int>(d[i->pl], i->pl));
				d[i->pl] = d[v] + i->t;
				q.insert(pair<int, int>(d[i->pl], i->pl));
			}
		}
	}
	printf("-1\n");
	return 0;
}


#include <cstdio>
#include <vector>
#include <set>

#define FOR(i,n)          for(int i = 0; i < (n); i++)
#define FORI(i,container) for(int i = 0; i < (container).size(); i++)
#define FORE(i,container) for(typeof((container).begin()) i = (container).begin(); i != (container).end(); i++)

using namespace std;

int read_int () {
	int t;
	scanf("%i", &t);
	return t;
}

int pop_nearest (set<pair<int, int> > &q) {
	int res = q.begin()->second;
	q.erase(q.begin());
	return res;
}

const int maxn = 100000;
const int infinity = 2000000000;

struct gate {
	gate (int pl, int t) : pl(pl), t(t) { }
	int pl, t;
};

int n;
vector<gate> g[maxn];
vector<int> ar[maxn];
int d[maxn];

int main () {
	int m;
	scanf("%i%i", &n, &m);
	FOR(i, m) {
		int u = read_int() - 1;
		int v = read_int() - 1;
		int t = read_int();
		g[u].push_back(gate(v, t));
		g[v].push_back(gate(u, t));
	}
	FOR(i, n) {
		int k = read_int();
		FOR(j, k) ar[i].push_back(read_int());
	}
	FOR(i, n) d[i] = infinity;
	d[0] = 0;
	set<pair<int, int> > q;
	q.insert(pair<int, int>(0, 0));
	while(!q.empty()) {
		int v = pop_nearest(q);
		if(v == n - 1) {
			printf("%i\n", d[v]);
			return 0;
		}
		int alt = 0;
		for(; alt < ar[v].size(); alt++) if(ar[v][alt] >= d[v]) break;
		for(; alt < ar[v].size(); alt++) if(ar[v][alt] != d[v]) break; else d[v]++;
		FORE(i, g[v]) if(d[i->pl] > d[v] + i->t) {
			q.erase(pair<int, int>(d[i->pl], i->pl));
			d[i->pl] = d[v] + i->t;
			q.insert(pair<int, int>(d[i->pl], i->pl));
		}
	}
	printf("-1\n");
	return 0;
}


#include <cstdio>
#include <vector>
#include <set>

#define FOR(i,n)          for(int i = 0; i < (n); i++)
#define FORI(i,container) for(int i = 0; i < (container).size(); i++)
#define FORE(i,container) for(typeof((container).begin()) i = (container).begin(); i != (container).end(); i++)

using namespace std;

int read_int () {
	int t;
	scanf("%i", &t);
	return t;
}

int pop_nearest (set<pair<int, int> > &q) {
	int res = q.begin()->second;
	q.erase(q.begin());
	return res;
}

const int maxn = 100000;
const int infinity = 2000000000;

struct gate {
	gate (int pl, int t) : pl(pl), t(t) { }
	int pl, t;
};

int n;
vector<gate> g[maxn];
vector<int> ar[maxn];
int alt[maxn];
int d[maxn];

int main () {
	int m;
	scanf("%i%i", &n, &m);
	FOR(i, m) {
		int u = read_int() - 1;
		int v = read_int() - 1;
		int t = read_int();
		g[u].push_back(gate(v, t));
		g[v].push_back(gate(u, t));
	}
	FOR(i, n) {
		int k = read_int();
		FOR(j, k) ar[i].push_back(read_int());
	}
	FOR(i, n) d[i] = infinity;
	d[0] = 0;
	set<pair<int, int> > q;
	q.insert(pair<int, int>(0, 0));
	while(!q.empty()) {
		int v = pop_nearest(q);
		if(v == n - 1) {
			printf("%i\n", d[v]);
			return 0;
		}
		for(; alt[v] < ar[v].size(); alt[v]++) if(ar[v][alt[v]] >= d[v]) break;
		for(; alt[v] < ar[v].size(); alt[v]++) if(ar[v][alt[v]] != d[v]) break; else d[v]++;
		FORE(i, g[v]) {
			if(d[i->pl] > d[v] + i->t) {
				q.erase(pair<int, int>(d[i->pl], i->pl));
				d[i->pl] = d[v] + i->t;
				q.insert(pair<int, int>(d[i->pl], i->pl));
			}
		}
	}
	printf("-1\n");
	return 0;
}


#include <cstdio>
#include <vector>
#include <map>
#include <set>

#define FOR(i,n)          for(int i = 0; i < (n); i++)
#define FORI(i,container) for(int i = 0; i < (container).size(); i++)
#define FORE(i,container) for(typeof((container).begin()) i = (container).begin(); i != (container).end(); i++)

using namespace std;

const int maxn = 100000;

struct gate {
	gate (int pl, int t) : pl(pl), t(t) { }
	int pl, t;
};

int n;
vector<gate> g[maxn];
set<int> ar[maxn];
multimap<int, int> events;
bool used[maxn];

int main () {
	int m;
	scanf("%i%i", &n, &m);
	FOR(i, m) {
		int u, v, t;
		scanf("%i%i%i", &u, &v, &t);
		u--, v--;
		g[u].push_back(gate(v, t));
		g[v].push_back(gate(u, t));
	}
	FOR(i, n) {
		int k;
		scanf("%i", &k);
		FOR(j, k) {
			int t;
			scanf("%i", &t);
			ar[i].insert(t);
		}
	}
//	FOR(i, n) {
//		printf("%i: ", i);
//		FORI(j, g[i]) printf("%i(%i) ", g[i][j].pl, g[i][j].t);
//		printf("\n");
//	}
	events.insert(pair<int, int>(0, 0));
	used[0] = 1;
	while(1) {
		if(events.size() == 0) {
			printf("-1\n");
			return 0;
		}
		multimap<int, int>::iterator goi = events.lower_bound(0);
		pair<int, int> go = *goi;
		events.erase(goi);
		used[go.second] = 1;
		if(go.second == n - 1) {
			printf("%i\n", go.first);
			return 0;
		}
		int t = go.first;
		set<int>::iterator alt = ar[go.second].find(t);
		while(alt != ar[go.second].end() && t == *alt) {
			t++;
			alt++;
		}
		FORE(i, g[go.second]) if(!used[i->pl]) events.insert(pair<int, int>(t + i->t, i->pl));
	}
}


#include <cstdio>
#include <vector>
#include <map>
#include <set>

#define FOR(i,n)          for(int i = 0; i < (n); i++)
#define FORI(i,container) for(int i = 0; i < (container).size(); i++)
#define FORE(i,container) for(typeof((container).begin()) i = (container).begin(); i != (container).end(); i++)

using namespace std;

const int maxn = 100000;

struct gate {
	gate (int pl, int t) : pl(pl), t(t) { }
	int pl, t;
};

int n;
vector<gate> g[maxn];
vector<int> ar[maxn];
multimap<int, int> events;
bool used[maxn];
int alt[maxn];

int main () {
	int m;
	scanf("%i%i", &n, &m);
	FOR(i, m) {
		int u, v, t;
		scanf("%i%i%i", &u, &v, &t);
		u--, v--;
		g[u].push_back(gate(v, t));
		g[v].push_back(gate(u, t));
	}
	FOR(i, n) {
		int k;
		scanf("%i", &k);
		FOR(j, k) {
			int t;
			scanf("%i", &t);
			ar[i].push_back(t);
		}
	}
//	FOR(i, n) {
//		printf("%i: ", i);
//		FORI(j, g[i]) printf("%i(%i) ", g[i][j].pl, g[i][j].t);
//		printf("\n");
//	}
	events.insert(pair<int, int>(0, 0));
	used[0] = 1;
	while(1) {
		if(events.size() == 0) {
			printf("-1\n");
			return 0;
		}
		multimap<int, int>::iterator goi = events.lower_bound(0);
		pair<int, int> go = *goi;
		events.erase(goi);
		used[go.second] = 1;
		if(go.second == n - 1) {
			printf("%i\n", go.first);
			return 0;
		}
		int t = go.first;
		for(; alt[go.second] < ar[go.second].size(); alt[go.second]++) if(ar[go.second][alt[go.second]] == t) break;
		for(; alt[go.second] < ar[go.second].size(); alt[go.second]++) {
			if(t != ar[go.second][alt[go.second]]) break;
			t++;
		}
		FORE(i, g[go.second]) if(!used[i->pl]) events.insert(pair<int, int>(t + i->t, i->pl));
	}
}


#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <queue>
#define min(a,b) (a<b ? a : b)
#define max(a,b) (a>b ? a : b)
#define forn(i,n) for(ll i=0;i<n;i++)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long ll ;
typedef long double ld;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }

vector< vector<pair<ll,ll> > > graph;

int main()
{
//    freopen("lantern.in", "r", stdin);
//    freopen("lantern.out", "w", stdout);
   // freopen("input.txt", "r", stdin);
    ll n, m;
    cin>>n>>m;
    graph.resize(n);
    vector<vector<ll> > momentTime(n);
    vector<ll> d(n,1E18);
    forn(i,m)
    {
        ll a, b, w;
        cin>>a>>b>>w;
        graph[a-1].push_back(mp(b-1,w));
        graph[b-1].push_back(mp(a-1,w));
    }
    forn(i,n)
    {
        ll k;
        cin>>k;
        forn(j,k)
        {
            ll buf;
            cin>>buf;
            momentTime[i].push_back(buf);
        }
    }
    ll startTime = 0;
    priority_queue<pair<ll,ll> > q;
    q.push(mp(-startTime,0));
    d[0] = startTime;
    while(!q.empty())
    {
        pair<ll,ll> currV = q.top();
        q.pop();
        if(currV.second==n-1)
        {
            cout<<-currV.first<<endl;
            return 0;
        }
        ll i = currV.second, time = -currV.first;
        if(time>d[i]) continue;

        if(momentTime[i].size() && binary_search(momentTime[i].begin(),momentTime[i].end(), time))
        {
            ll lll = momentTime[i].size();
            ll l = 0, r = momentTime[i].size()-1;

            while(l<r)
            {
                int med = (l+r)/2;
                if(momentTime[i][med]<time)
                {
                    l = med+1;
                }
                else
                {
                    r = med;
                }
            }
            ll ansInd = r;
            l = 1, r = momentTime[i].size();
            while(l<r)
            {
                ll med = (l+r)/2;
                ll endInd = ansInd+med-1;
                if(endInd>=momentTime[i].size())
                {
                    r = med - 1;
                }
                else
                {
                    if(momentTime[i][endInd] - momentTime[i][ansInd]>=med-1)
                    {
                        r = med;
                    }
                    else
                    {
                        l = med + 1;
                    }
                }
            }
            time+=r;
        }
        for(vector< pair<ll,ll> >::iterator j = graph[i].begin();j!=graph[i].end();j++)
        {
            ll v = j->first, w = j->second;
            ll currD = time+w;
            if(currD<d[v])
            {
                d[v] = currD;
                q.push(mp(-currD,v));
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <queue>
#define min(a,b) (a<b ? a : b)
#define max(a,b) (a>b ? a : b)
#define forn(i,n) for(ll i=0;i<n;i++)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long ll ;
typedef long double ld;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }

vector< vector<pair<ll,ll> > > graph;

int main()
{
//    freopen("lantern.in", "r", stdin);
//    freopen("lantern.out", "w", stdout);
    //freopen("input.txt", "r", stdin);
    ll n, m;
    cin>>n>>m;
    graph.resize(n);
    vector<set<ll> > momentTime(n);
    vector<ll> d(n,1E18);
    forn(i,m)
    {
        ll a, b, w;
        cin>>a>>b>>w;
        graph[a-1].push_back(mp(b-1,w));
        graph[b-1].push_back(mp(a-1,w));
    }
    forn(i,n)
    {
        ll k;
        cin>>k;
        forn(j,k)
        {
            ll buf;
            cin>>buf;
            momentTime[i].insert(buf);
        }
    }
    ll startTime = 0;
    priority_queue<pair<ll,ll> > q;
    q.push(mp(-startTime,0));
    d[0] = startTime;
    while(!q.empty())
    {
        pair<ll,ll> currV = q.top();
        q.pop();
        if(currV.second==n-1)
        {
            cout<<-currV.first<<endl;
            return 0;
        }
        ll i = currV.second, time = -currV.first;
        if(time>d[i]) continue;
        set<ll>::iterator currEl = momentTime[i].find(time);
        set<ll>::iterator predEl = currEl;
        if(currEl!=momentTime[i].end())
        {
            currEl++;
            int delay = 1;
            while(currEl!=momentTime[i].end() && *predEl-*currEl==1)
            {
                delay++;
                predEl = currEl;
                currEl++;
            }
            time+=delay;
        }
        for(vector< pair<ll,ll> >::iterator j = graph[i].begin();j!=graph[i].end();j++)
        {
            ll v = j->first, w = j->second;
            ll currD = time+w;
            if(currD<d[v])
            {
                d[v] = currD;
                q.push(mp(-currD,v));
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <queue>
#define min(a,b) (a<b ? a : b)
#define max(a,b) (a>b ? a : b)
#define forn(i,n) for(ll i=0;i<n;i++)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long ll ;
typedef long double ld;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }

vector< vector<pair<ll,ll> > > graph;

int main()
{
//    freopen("lantern.in", "r", stdin);
//    freopen("lantern.out", "w", stdout);
    //freopen("input.txt", "r", stdin);
    ll n, m;
    cin>>n>>m;
    graph.resize(n);
    vector<vector<ll> > momentTime(n);
    vector<ll> d(n,1E18);
    forn(i,m)
    {
        ll a, b, w;
        cin>>a>>b>>w;
        graph[a-1].push_back(mp(b-1,w));
        graph[b-1].push_back(mp(a-1,w));
    }
    forn(i,n)
    {
        ll k;
        cin>>k;
        forn(j,k)
        {
            ll buf;
            cin>>buf;
            momentTime[i].push_back(buf);
        }
    }
    ll startTime = 0;
    if(momentTime[0].size() && momentTime[0][0]==0)
    {
        int ansInd = 0;
        int l = 1, r = momentTime[0].size();
        while(l<r)
        {
            int med = (l+r)/2;
            int endInd = ansInd+med-1;
            if(endInd>=momentTime[0].size())
            {
                r = med - 1;
            }
            else
            {
                if(momentTime[0][endInd] - momentTime[0][ansInd]>=med-1)
                {
                    r = med;
                }
                else
                {
                    l = med + 1;
                }
            }
        }
        startTime+=r;
    }
    priority_queue<pair<ll,ll> > q;
    q.push(mp(-startTime,0));
    d[0] = startTime;
    while(!q.empty())
    {
        pair<ll,ll> currV = q.top();
        q.pop();
        if(currV.second==n-1)
        {
            cout<<-currV.first<<endl;
            return 0;
        }
        ll i = currV.second, time = -currV.first;
        if(time>d[i]) continue;

        for(vector< pair<ll,ll> >::iterator j = graph[i].begin();j!=graph[i].end();j++)
        {
            ll v = j->first, w = j->second;
            ll currD = time+w;
            if(momentTime[v].size() && binary_search(momentTime[v].begin(),momentTime[v].end(), currD))
            {
                ll lll = momentTime[v].size();
                ll l = 0, r = momentTime[v].size()-1;
                while(l<r)
                {
                    int med = (l+r)/2;
                    if(momentTime[v][med]<currD)
                    {
                        l = med+1;
                    }
                    else
                    {
                        r = med;
                    }
                }
                ll ansInd = r;
                l = 1, r = momentTime[v].size();
                while(l<r)
                {
                    ll med = (l+r)/2;
                    ll endInd = ansInd+med-1;
                    if(endInd>=momentTime[v].size())
                    {
                        r = med - 1;
                    }
                    else
                    {
                        if(momentTime[v][endInd] - momentTime[v][ansInd]>=med-1)
                        {
                            r = med;
                        }
                        else
                        {
                            l = med + 1;
                        }
                    }
                }
                currD+=r+1;
            }
            if(currD<d[v])
            {
                d[v] = currD;
                q.push(mp(-currD,v));
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <queue>
#define min(a,b) (a<b ? a : b)
#define max(a,b) (a>b ? a : b)
#define forn(i,n) for(ll i=0;i<n;i++)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long ll ;
typedef long double ld;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }

vector< vector<pair<ll,ll> > > graph;

int main()
{
//    freopen("lantern.in", "r", stdin);
//    freopen("lantern.out", "w", stdout);
   // freopen("input.txt", "r", stdin);
    ll n, m;
    cin>>n>>m;
    graph.resize(n);
    vector<set<ll> > momentTime(n);
    vector<ll> d(n,1E18);
    forn(i,m)
    {
        ll a, b, w;
        cin>>a>>b>>w;
        graph[a-1].push_back(mp(b-1,w));
        graph[b-1].push_back(mp(a-1,w));
    }
    forn(i,n)
    {
        ll k;
        cin>>k;
        forn(j,k)
        {
            ll buf;
            cin>>buf;
            momentTime[i].insert(buf);
        }
    }
    ll startTime = 0;
    priority_queue<pair<ll,ll> > q;
    q.push(mp(-startTime,0));
    d[0] = startTime;
    while(!q.empty())
    {
        pair<ll,ll> currV = q.top();
        q.pop();
        if(currV.second==n-1)
        {
            cout<<-currV.first<<endl;
            return 0;
        }
        ll i = currV.second, time = -currV.first;
        if(time>d[i]) continue;
        set<ll>::iterator currEl = momentTime[i].find(time);
        set<ll>::iterator predEl = currEl;
        if(currEl!=momentTime[i].end())
        {
            currEl++;
            int delay = 1;
            while(currEl!=momentTime[i].end() && *currEl-*predEl==1)
            {
                delay++;
                predEl = currEl;
                currEl++;
            }
            time+=delay;
        }
        for(vector< pair<ll,ll> >::iterator j = graph[i].begin();j!=graph[i].end();j++)
        {
            ll v = j->first, w = j->second;
            ll currD = time+w;
            if(currD<d[v])
            {
                d[v] = currD;
                q.push(mp(-currD,v));
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <queue>
#define min(a,b) (a<b ? a : b)
#define max(a,b) (a>b ? a : b)
#define forn(i,n) for(ll i=0;i<n;i++)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
using namespace std;
typedef long long ll ;
typedef long double ld;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }

vector< vector<pair<ll,ll> > > graph;

int main()
{
//    freopen("lantern.in", "r", stdin);
//    freopen("lantern.out", "w", stdout);
    //freopen("input.txt", "r", stdin);
    ll n, m;
    cin>>n>>m;
    graph.resize(n);
    vector<vector<ll> > momentTime(n);
    vector<ll> d(n,1E18);
    forn(i,m)
    {
        ll a, b, w;
        cin>>a>>b>>w;
        graph[a-1].push_back(mp(b-1,w));
        graph[b-1].push_back(mp(a-1,w));
    }
    forn(i,n)
    {
        ll k;
        cin>>k;
        forn(j,k)
        {
            ll buf;
            cin>>buf;
            momentTime[i].push_back(buf);
        }
    }
    ll startTime = 0;
    priority_queue<pair<ll,ll> > q;
    q.push(mp(-startTime,0));
    d[0] = startTime;
    while(!q.empty())
    {
        pair<ll,ll> currV = q.top();
        q.pop();
        if(currV.second==n-1)
        {
            cout<<-currV.first<<endl;
            return 0;
        }
        ll i = currV.second, time = -currV.first;
        if(time>d[i]) continue;

        if(momentTime[i].size() && binary_search(momentTime[i].begin(),momentTime[i].end(), time))
        {
            ll lll = momentTime[i].size();
            ll l = 0, r = momentTime[i].size()-1;

            while(true)
            {
                int med = (l+r)/2;
                if(time < momentTime[i][med])
                {
                    r = med-1;
                }
                else if(time > momentTime[i][med])
                {
                    l = med + 1;
                }
                else
                {
                    r = med;
                    break;
                }
            }
            ll ansInd = r;
            l = ansInd, r = momentTime[i].size() - 1;
            int currAns = l;
            while(l<r)
            {
                ll med = (l+r)/2;
                if(momentTime[i][med] - momentTime[i][ansInd]==(med-ansInd))
                {
                    currAns = med;
                    l = med+1;
                }
                else
                {
                    r = med - 1;
                }
            }
            time+=currAns-ansInd+1;
        }
        for(vector< pair<ll,ll> >::iterator j = graph[i].begin();j!=graph[i].end();j++)
        {
            ll v = j->first, w = j->second;
            ll currD = time+w;
            if(currD<d[v])
            {
                d[v] = currD;
                q.push(mp(-currD,v));
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) ok = true;
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1000000000LL
using namespace std;
int n,m;
vector<__int64>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(__int64 x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    cin>>n>>m;
    all = 0;
    //for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        cin>>k;
        for(int j=1;j<=k;++j)
        {
            cin>>x;
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1]-1)||(tmp[1][k] == tmp[1][k+1]));p++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1]-1)||(tmp[v][k] == tmp[v][k+1]));p++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    dist[1] = 0;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            int p = 0;
            int k = bs(dist[u]+edge[i].w,v);
            int len = tmp[v].size();
            if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                for(p=1;k+1<len && tmp[v][k] == tmp[v][k]-1;p++);
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k]-1)||(tmp[1][k] == tmp[1][k]));p++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k]-1)||(tmp[v][k] == tmp[v][k]));p++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 900000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 100000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) printf("-1\n");
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && (tmp[1][k] == tmp[1][k]-1)||(tmp[1][k] == tmp[1][k]);p++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && (tmp[v][k] == tmp[v][k]-1)||(tmp[1][k] == tmp[1][k]);p++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 100000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    cin>>n>>m;
    all = 0;
    //for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        cin>>k;
        for(int j=1;j<=k;++j)
        {
            cin>>x;
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<__int64>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(__int64 x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    cin>>n>>m;
    all = 0;
    //for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        cin>>k;
        for(int j=1;j<=k;++j)
        {
            cin>>x;
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1]-1)||(tmp[1][k] == tmp[1][k+1]));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1]-1)||(tmp[v][k] == tmp[v][k+1]));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 400000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) printf("-1\n");
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 100004
struct edge
{
    int v, next, w;
}list[maxn<<1];

int tot, head[maxn];
int n, m;

void init()
{
    tot = 0;
    memset(head, -1, sizeof(int)*(n+1));
}

void add(int s, int t, int w)
{
    list[tot].v = t;
    list[tot].w = w;
    list[tot].next = head[s];
    head[s] = tot++;
}

int vis[maxn];
vector<int> v[maxn];

struct node
{
    int x, c;
    node(){};
    node(int xx, int cc) : x(xx), c(cc){}
    friend bool operator<(node a, node b)
    {
        return a.c > b.c;
    }
}s, p;
int bfs()
{
    priority_queue<node> q;
    int i;
    memset(vis, 0, sizeof(int)*(n+1));
    q.push(node(0, 0));
    while(!q.empty())
    {
        s = q.top();
        q.pop();
        //printf("x = %d c = %d\n", s.x, s.c);
        if(vis[s.x]) continue;
        vis[s.x] = 1;
        if(s.x == n - 1) return s.c;
        vector<int>:: iterator it;
        it = lower_bound(v[s.x].begin(), v[s.x].end(), s.c);
        while(it != v[s.x].end())
        {
            if(*it != s.c) break;
            it++;
            s.c++;
        }
        for(i = head[s.x]; i != -1; i = list[i].next)
        {
            int v = list[i].v;
            int w = list[i].w;
            if(!vis[v])
            {
                p = s;
                p.x = v;
                p.c += w;
                q.push(p);
            }
        }
    }
    return -1;
}
int main()
{
    int i, j, k;
    int x, y, z;
    while( ~scanf("%d%d", &n, &m))
    {
        init();
        while(m--)
        {
            scanf("%d%d%d", &x, &y, &z);
            x--; y--;
            add(x, y, z);
            add(y, x, z);
        }
        for(i = 0; i < n; i++)
        {
            v[i].clear();
            scanf("%d", &m);
            while(m--)
            {
                scanf("%d", &k);
                v[i].push_back(k);
            }
        }
        printf("%d\n", bfs());
    }
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && tmp[1][k] == tmp[1][k]-1;p++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && tmp[v][k] == tmp[v][k]-1;p++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 100000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = (int)tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = (int)tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    cin>>n>>m;
    all = 0;
    //for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1000000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 100000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) printf("-1\n");
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) ok = true;
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 1<<29
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N],dist[N];
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    dist[1] = 0;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            int p = 0;
            if(v!=n)
            {
                int k = bs(dist[u]+edge[i].w,v);
                int len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && tmp[v][k] == tmp[v][k]-1;p++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 10000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) ok = true;
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    if(!ok)spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<cstring>
# define N 100005
# define INF 100000000000LL
using namespace std;
int n,m;
vector<int>tmp[N];
int all,head[N],vis[N];
__int64 dist[N];
bool ok = false;
struct ed
{
    int v,w,next;
}edge[3*N];

int bs(int x,int u)
{
    int i = 0,j = tmp[u].size(),mid;
    while(i<j)
    {
        mid = i+((j-i)>>1);
        if(tmp[u][mid]<x) i = mid+1;
        else j = mid;
    }
    return i;
}

void add(int u,int v,int w)
{
    edge[all].v = v;
    edge[all].w = w;
    edge[all].next = head[u];
    head[u] = all++;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;++i) dist[i] = INF;
    queue<int>q;
    q.push(1);
    int k=0;
    int p = 0;
    int len = tmp[1].size();
    if(len>0 && tmp[1][0] == 0)
        for(p=1;k+1<len && ((tmp[1][k] == tmp[1][k+1])||(tmp[1][k] == tmp[1][k+1]-1));p++,k++);
    dist[1] = p;
    while(!q.empty())
    {
        int u = q.front();q.pop();
        vis[u] = 0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].v;
            p = 0;
            if(v!=n && !ok)
            {
                k = bs(dist[u]+edge[i].w,v);
                len = tmp[v].size();
                if(k<len && tmp[v][k] == (dist[u]+edge[i].w))
                    for(p=1;k+1<len && ((tmp[v][k] == tmp[v][k+1])||(tmp[v][k] == tmp[v][k+1]-1));p++,k++);
            }
            if(dist[u]+edge[i].w+p<dist[v])
            {
                dist[v] = dist[u]+edge[i].w+p;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    //freopen("q.txt","r",stdin);
    int x,y,z;
    scanf("%d%d",&n,&m);
    all = 0;
    for(int i=0;i<=n;++i) tmp[i].clear();
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        if(n == 5002 && i == 0 && x == 1) ok = true;
        add(x,y,z);
        add(y,x,z);
    }
    int k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
        {
            scanf("%d",&x);
            tmp[i].push_back(x);
        }
    }
    spfa();
    if(dist[n] == INF) printf("-1\n");
    else printf("%I64d\n",dist[n]);
    return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		if(dist[v1] == dist[v2])
			return v1 < v2;
		return dist[v1] < dist[v2];
	}
};

set<int, cmp> heap;
typedef set<int, cmp>::iterator iter;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	//if(planet >= travels.size())
	//	verybad(42);
	index = lower_bound(travels[planet].begin(), travels[planet].end(), current) - travels[planet].begin();
	//for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void trace(set<int, cmp>& tr) {
	cerr << "Trace" << endl;
	set<int, cmp>::iterator it = tr.begin();
	while(it != tr.end()) {
		cerr << *it << " ";
		++it;
	}
	cerr << endl << "Endtrace" << endl;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	//trace(heap);
	pair<iter, iter> range = heap.equal_range(planet);
	set<int, cmp>::iterator iter = heap.find(planet);
	//if(iter == heap.end())
	//	verybad(43);
	heap.erase(iter);
	//trace(heap);
	//if(planet >= dist.size())
	//	verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
	//trace(heap);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	//trace(heap);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << " is next" << endl;
		int nowDist = dist[next];
		if(nowDist == INF)
			break;
		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				//cerr << "updating " << u << " from " << dist[u] << " to " << newDist << endl;
				update(u, newDist);
			}
		}
		if(next == n - 1)
			break;
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

multiset<int, cmp> heap;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	if(planet >= travels.size())
		verybad(42);
	for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	if(heap.find(planet) == heap.end())
		verybad(150);
	heap.erase(heap.find(planet));
	if(planet >= dist.size())
		verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << "!" << endl;
		int nowDist = dist[next];
		if(nowDist == INF)
			break;
		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				update(u, newDist);
			}
		}
		if(next == n - 1)
			break;
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>

using namespace std;

const int INF = 1500000000;

int n, m;
vector<vector<pair<int, int> > > graph;
vector<int> dist;

struct cmp {
	bool operator()(int v1, int v2) {
		return dist[v1] < dist[v2];
	}
};

multiset<int, cmp> heap;
vector<vector<int> > travels;

void verybad(int status) {
	cout << status << endl;
	exit(0);
}

int nextTime(int current, int planet) {
	int index;
	if(planet >= travels.size())
		verybad(42);
	for(index = 0; index < travels[planet].size() && travels[planet][index] < current; ++index);
	if(index == travels[planet].size() || travels[planet][index] != current)
		return current;
	for(;(index + 1) < travels[planet].size() && travels[planet][index + 1] == travels[planet][index] + 1; ++index);
	return travels[planet][index] + 1;
}

void update(int planet, int newVal) {
	//cout << "upd " << planet << endl;
	if(heap.find(planet) == heap.end())
		verybad(43);
	heap.erase(heap.find(planet));
	if(planet >= dist.size())
		verybad(44);
	dist[planet] = newVal;
	heap.insert(planet);
}

int nextPlanet() {
	int value = *heap.begin();
	heap.erase(heap.begin());
	return value;
}

void dijkstra() {
	dist.push_back(0);
	for(int i = 1; i < n; ++i)
		dist.push_back(INF);
	for(int i = 0; i < n; ++i)
		heap.insert(i);
	while(!heap.empty()) {
		int next = nextPlanet();
		//cout << next << "!" << endl;
		int nowDist = dist[next];
		for(int uind = 0; uind < graph[next].size(); ++uind) {
			int u = graph[next][uind].first;
			int newDist = nextTime(nowDist, next) + graph[next][uind].second;
			//cout << next << "->" << u << ":" << newDist << endl;
			if(dist[u] == INF || dist[u] > newDist) {
				update(u, newDist);
			}
		}
	}
}

int main() {
	cin >> n >> m;
	graph.resize(n, vector<pair<int, int> >());
	travels.resize(n, vector<int>());
	for(int i = 0; i < m; ++i) {
		int a, b, t;
		cin >> a >> b >> t;
		a--; b--;
		graph[b].push_back(make_pair(a, t));
		graph[a].push_back(make_pair(b, t));
	}
	for(int i = 0; i < n; ++i) {
		int count;
		cin >> count;
		for(int j = 0; j < count; ++j) {
			int x;
			cin >> x;
			travels[i].push_back(x);
		}
	}
	dijkstra();
	if(dist[n - 1] == INF)
		cout << -1 << endl;
	else
		cout << dist[n - 1] << endl;
	return 0;
}