#include <bits/stdc++.h>
#include <windows.h>
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define db double
#define ldb long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mkp make_pair
#define eb emplace_back
#define SZ(S) (int)S.size()
//#define mod 998244353
//#define mod 1000000007
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
using namespace std;
template <class T>
void chkmax(T &x,T y){
if(x < y) x = y;
}
template <class T>
void chkmin(T &x,T y){
if(x > y) x = y;
}
inline int popcnt(int x){
return __builtin_popcount(x);
}
inline int ctz(int x){
return __builtin_ctz(x);
}
/*ll power(ll p,int k = mod - 2){
ll ans = 1;
while(k){
if(k % 2 == 1) ans = ans * p % mod;
p = p * p % mod;
k /= 2;
}
return ans;
}*/
int n,m,k;
vector <pii> G[200005];
int getval(int u,int v){//u->v 的边权?
// printf("try getval %d->%d\n",u,v);
int pos = lower_bound(G[u].begin(),G[u].end(),mkp(v,0)) - G[u].begin();
if(pos >= SZ(G[u]) || G[u][pos].first != v) assert(0);
return G[u][pos].second;
}
int N = 1;//acam 节点从 1 开始编号
map <int,int> ch[400005];
vector <int> ord;
int fail[400005],_lst[400005],frp[400005],str[200005];
int insert(int L){
int u = 1;
rep(i,1,L){
if(!ch[u][str[i]]){
ch[u][str[i]] = ++N;
_lst[N] = str[i];
}
u = ch[u][str[i]];
}
return u;
}
queue <int> QQ;
void build(){
for(pii I:ch[1]){
QQ.push(I.second);
fail[I.second] = 1;
}
while(!QQ.empty()){
int u = QQ.front();
QQ.pop();
ord.eb(u);
for(pii I:ch[u]){
int v = I.second,p = fail[u];
while(p > 1 && ch[p].find(I.first) == ch[p].end()) p = fail[p];
if(ch[p].find(I.first) != ch[p].end()) p = ch[p][I.first];
fail[v] = p;
QQ.push(v);
}
}
}
ll dis[400005];
int cnt;
int T[400005],_st[200005];
struct NODE{
int val,l,r;
}tree[13000005];
#define ls(rt) tree[rt].l
#define rs(rt) tree[rt].r
void pushup(int rt){
tree[rt].val = 0;
if(ls(rt)) tree[rt].val |= tree[ls(rt)].val;
if(rs(rt)) tree[rt].val |= tree[rs(rt)].val;
}
int upload(int Q,int l,int r,int pos,int C){
int rt = ++cnt;
tree[rt] = tree[Q];
if(l == r){
tree[rt].val = C;
return rt;
}
int mid = (l + r) >> 1;
if(pos <= mid) ls(rt) = upload(ls(Q),l,mid,pos,C);
else rs(rt) = upload(rs(Q),mid+1,r,pos,C);
pushup(rt);
return rt;
}
priority_queue <pll> Q;
void query(int rt,int l,int r,int u){
if(!tree[rt].val) return;
if(l == r){
int p = tree[rt].val,v = ch[p][l];
// printf("u=%d p=%d l=%d v=%d\n",u,p,l,v);
if(!frp[v] && dis[v] > dis[u] + getval(_lst[u],l)){
dis[v] = dis[u] + getval(_lst[u],l);
// printf("upd %d %lld\n",v,dis[v]);
Q.push(mkp(-dis[v],v));
}
tree[rt].val = 0;
return;
}
int mid = (l + r) >> 1;
if(ls(rt)) query(ls(rt),l,mid,u);
if(rs(rt)) query(rs(rt),mid+1,r,u);
tree[rt].val = 0;
return;
}
void travel(int rt,int l,int r){
if(l == r){
printf("node %d [%d,%d] %d\n",rt,l,r,tree[rt].val);
return;
}
int mid = (l + r) >> 1;
if(ls(rt)) travel(ls(rt),l,mid);
if(rs(rt)) travel(rs(rt),mid+1,r);
printf("node %d [%d,%d] %d\n",rt,l,r,tree[rt].val);
}
void dijsktra(){
memset(dis,0x3f,sizeof(dis));
dis[ch[1][1]] = 0;
Q.push(mkp(0,ch[1][1]));
while(!Q.empty()){
int u = Q.top().second;
if(-Q.top().first > dis[u]){
Q.pop();
continue;
}
Q.pop();
// printf("find %d dis %lld\n",u,dis[u]);
query(T[u],1,n,u);
}
}
int main(){
// freopen("test.in","r",stdin);
scanf("%d%d%d",&n,&m,&k);
rep(i,1,m){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].eb(mkp(v,w));
}
rep(u,1,n) sort(G[u].begin(),G[u].end());
rep(i,1,k){
int p;
scanf("%d",&p);
rep(j,1,p) scanf("%d",&str[j]);
frp[insert(p)] = 1;
}
rep(u,1,n){
str[1] = u;
insert(1);
}
/* printf("NN=%d\n",N);
rep(u,1,N){
printf("node %d fail %d\n",u,fail[u]);
for(pii I:ch[u]) printf("->%d id %d\n",I.first,I.second);
}*/
build();
/* rep(u,1,N){
printf("node %d fail %d\n",u,fail[u]);
for(pii I:ch[u]) printf("->%d id %d\n",I.first,I.second);
}*/
rep(u,1,n) for(pii I:G[u]) _st[u] = upload(_st[u],1,n,I.first,1);
/* rep(u,1,n){
printf("travel st %d\n",u);
travel(_st[u],1,n);
}*/
for(int u:ord){
if(fail[u] == 1) T[u] = _st[_lst[u]];
else T[u] = T[fail[u]];
for(pii I:ch[u]) T[u] = upload(T[u],1,n,I.first,u);
/* if(u == 15){
printf("Qwqqwqqw\n");
travel(T[u],1,n);
for(pii I:ch[u]) printf("?? %d\n",I.first);
}*/
}
dijsktra();
ll ans = linf;
rep(u,1,N) if(_lst[u] == n) chkmin(ans,dis[u]);
// rep(u,1,N) printf("node %d dis=%lld\n",u,dis[u]);
// printf("\n");
if(ans > 1e15) printf("-1\n");
else printf("%lld\n",ans);
return 0;
}