#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
const int INF = 0x7fffffff;
vector<int> G[MAXN];
int head[MAXN];
struct HeapNode {
  int d, u;
  bool operator<(const HeapNode &a) const { return d > a.d; }
};
struct Node {
  int v;
  int w;
  int next;
} edge[2 * MAXN];
int n, m, edge_cnt;
void addedge(int u, int v, int w) {
  edge[edge_cnt].v = v;
  edge[edge_cnt].next = head[u];
  edge[edge_cnt].w = w;
  head[u] = edge_cnt++;
}
int Dijikstra() {
  priority_queue<HeapNode> Q;
  int d[MAXN], vis[MAXN];
  for (int i = 1; i <= n; i++) d[i] = INF;
  memset(vis, 0, sizeof(vis));
  d[1] = 0;
  Q.push((HeapNode){0, 1});
  while (!Q.empty()) {
    HeapNode x = Q.top();
    Q.pop();
    int u = x.u;
    if (vis[u]) continue;
    vis[u] = 1;
    if (u == n) return d[n];
    vector<int>::iterator it;
    it = lower_bound(G[u].begin(), G[u].end(), d[u]);
    while (it != G[u].end()) {
      if (*it != d[u]) break;
      it++;
      d[u]++;
    }
    for (int i = head[u]; i != -1; i = edge[i].next) {
      int v = edge[i].v;
      int w = edge[i].w;
      if (d[v] > d[u] + w) d[v] = d[u] + w;
      Q.push((HeapNode){d[v], v});
    }
  }
  return -1;
}
int main() {
  int u, v, w;
  while (scanf("%d%d", &n, &m) != EOF) {
    edge_cnt = 0;
    memset(head, -1, sizeof(head));
    for (int i = 1; i <= n; i++) G[i].clear();
    for (int i = 0; i < m; i++) {
      scanf("%d%d%d", &u, &v, &w);
      addedge(u, v, w);
      addedge(v, u, w);
    }
    for (int i = 1; i <= n; i++) {
      int k, x;
      scanf("%d", &k);
      for (int j = 0; j < k; j++) {
        scanf("%d", &x);
        G[i].push_back(x);
      }
    }
    printf("%d\n", Dijikstra());
  }
  return 0;
}
