#include <iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int monster[3005];
int na = 10000000;
int ans = na;
int n, m, p,k;
int head[205];
int to[3005];
int nt[3005];
int t[3005];
int cnt = 0;
bool vis[205][1<<15];
struct node { int now; int sword;int val; bool operator<(const node& a)const{ return val > a.val; } };
int persword[205];
int dis[205][1 << 15];
priority_queue<node>que;
int main()
{
cin >> n >> m >> p >> k;
int w, q, r;
for (int i = 1;i <= 200; i++) {
for (int j =0; j <= 1 <<14; j++) {
dis[i][j] =na;
}
}
for (int i = 1; i <= k; i++) {
cin >> w >> q;
for (int j = 1; j <= q; j++) {
cin >> r;
persword[w] |= 1 << r;
}
}
int a,b,tt, s, u;
for (int i = 1; i <= m; i++) {
cin >> a >> b >> tt >> s;
nt[++cnt] = head[a];
to[cnt] = b;
t[cnt] = tt;
head[a] = cnt;
for (int j = 1; j <= s; j++) {
cin >> u;
monster[cnt] |= 1 << u;
}
nt[++cnt] = head[b];
to[cnt] = a;
t[cnt] = tt;
head[b] = cnt;
monster[cnt] = monster[cnt - 1];
}
int begsword = persword[1];
dis[1][begsword] =0;
vis[1][begsword] = true;
que.push({ 1,begsword,0 });
while (!que.empty()) {
node cur = que.top();
que.pop();
vis[cur.now][cur.sword]= false;
if (cur.now == n) { cout << cur.val << endl; return 0;}
for (int ei = head[cur.now]; ei; ei = nt[ei]) {
int tempsword = cur.sword|monster[ei];
if (tempsword != cur.sword) { continue; }
int newsword = cur.sword | persword[to[ei]];
if (dis[to[ei]][newsword] > dis[cur.now][cur.sword] + t[ei]) {
dis[to[ei]][newsword] = dis[cur.now][cur.sword] + t[ei];
if (!vis[to[ei]][newsword]) {
que.push({ to[ei], newsword, dis[to[ei]][newsword] });
vis[to[ei]][newsword] = true;
}
}
}
}
cout << -1 << endl;
}