#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet {
class Graph {
 public:
  long long head[155555];
  long long EdgeCount;
  struct Edge {
    long long To, Label, Next;
  } Ed[155555 << 2];
  void clear(long long _V = 155555, long long _E = 155555 << 2) {
    memset(Ed, -1, sizeof(Edge) * (_E));
    memset(head, -1, sizeof(long long) * (_V));
    EdgeCount = -1;
  }
  void AddEdge(long long u, long long v, long long w = 1) {
    Ed[++EdgeCount] = (Edge){v, w, head[u]};
    head[u] = EdgeCount;
  }
  void Add2(long long u, long long v, long long w = 1) {
    AddEdge(u, v, w);
    AddEdge(v, u, w);
  }
  long long Start(long long u) { return head[u]; }
  long long To(long long u) { return Ed[u].To; }
  long long Label(long long u) { return Ed[u].Label; }
  long long Next(long long u) { return Ed[u].Next; }
} G;
void R1(long long &x) {
  x = 0;
  char c = getchar();
  long long f = 1;
  while (c < '0' or c > '9') f = (c == '-') ? -1 : 1, c = getchar();
  while (c >= '0' and c <= '9')
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  x = (f == 1) ? x : -x;
}
long long n, m;
vector<pair<long long, long long> > wait[155555];
void Input() {
  R1(n), R1(m);
  G.clear();
  for (long long i = 1; i <= m; ++i) {
    long long u, v, w;
    R1(u), R1(v), R1(w);
    G.Add2(u, v, w);
  }
  for (long long i = 1; i <= n; ++i) {
    long long k;
    R1(k);
    for (long long j = 1; j <= k; ++j) {
      long long x;
      R1(x);
      wait[i].push_back(make_pair(x, 0));
    }
  }
}
struct node {
  long long v, w;
};
bool operator<(node a, node b) { return a.w > b.w; }
priority_queue<node> Q;
long long dis[155555], vis[155555];
long long Find(long long u, long long w) {
  if (wait[u].size() == 0) return -1;
  long long l = 0, r = (long long)wait[u].size() - 1;
  long long ans = -1;
  while (l <= r) {
    long long mid = (l + r) >> 1;
    if (wait[u][mid].first <= w)
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  return wait[u][ans].first == w ? ans : -1;
}
void Dijkstra(long long s) {
  memset(dis, 0x3f, sizeof(dis));
  memset(vis, 0, sizeof(vis));
  while (!Q.empty()) Q.pop();
  if (wait[s].size()) {
    if (wait[s][0].first == 0)
      Q.push((node){s, wait[s][0].second}), dis[s] = wait[s][0].second;
  }
  if (!wait[s].size() or wait[s][0].first) Q.push((node){s, 0}), dis[s] = 0;
  while (!Q.empty()) {
    node Min = Q.top();
    Q.pop();
    long long u = Min.v;
    if (Min.w > dis[u]) continue;
    vis[u] = 1;
    for (long long i = G.Start(u), __v = G.To(i); ~i;
         i = G.Next(i), __v = G.To(i)) {
      long long v = __v;
      if (vis[v]) continue;
      long long w = G.Label(i) + dis[u];
      if (v == n) {
        dis[v] = min(dis[v], w);
      }
      long long pos = Find(v, w);
      if (pos != -1) {
        long long d = wait[v][pos].second;
        if (d < dis[v]) dis[v] = d, Q.push((node){v, dis[v]});
      } else {
        if (w < dis[v]) dis[v] = w, Q.push((node){v, dis[v]});
      }
    }
  }
  if (dis[n] == 0x3f3f3f3f3f3f3f3fll)
    puts("-1");
  else
    printf("%lld\n", dis[n]);
}
void Soviet() {
  for (long long i = 1; i <= n; ++i) {
    long long s = wait[i].size();
    for (long long j = s - 1; j >= 0; --j) {
      if (j == s - 1) wait[i][j].second = wait[i][j].first + 1;
      if (j < s - 1)
        wait[i][j].second = (wait[i][j].first + 1 == wait[i][j + 1].first)
                                ? wait[i][j + 1].second
                                : wait[i][j].first + 1;
    }
  }
  Dijkstra(1);
}
void IsMyWife() {
  Input();
  Soviet();
}
}  // namespace Flandre_Scarlet
int main() {
  Flandre_Scarlet::IsMyWife();
  getchar();
  getchar();
  return 0;
}
