#include<iostream>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<tuple>
using namespace std;

#define MAX_N 1000
#define MAX_H 50
#define MAX_K 10
#define INF (1LL<<62)
#define WHITE 0
#define GRAY 1
#define BLACK 2

long long N, M, H, K, S, T, P, maxn;
vector<tuple<long long, long long, long long, long long>>x[MAX_N];//0->ikisaki,1->cost,2->time,3->group
long long a1, a2, a3, a4, a5;
long long v[(1 << MAX_K)][MAX_K + 1], y[(1 << MAX_K)], w[MAX_K + 1];
long long dist[MAX_N][MAX_H], color[MAX_N];
long long dp[(1 << MAX_K)];

priority_queue<pair<long long, long long>, vector<pair<long long, long long>>, greater<pair<long long, long long>>>Q[MAX_H];

long long dijkstra(vector<long long>U) {

	for (int i = 0; i < MAX_N; i++)
	{
		for (int j = 0; j < MAX_H; j++)
		{
			dist[i][j] = INF;
		}
		color[i] = WHITE;
	}

	dist[S][0] = 0LL;
	Q[0].push(make_pair(0, S));

	while (true)
	{
		int sumsize = 0;
		for (int i = 0; i < MAX_H; i++) {
			sumsize += Q[i].size();
		}

		if (sumsize == 0)
		{
			long long minx2 = INF;
			for (int j = 0; j < MAX_H; j++) {
				minx2 = min(minx2, dist[T][j]);
			}
			return minx2;
		}

		for (int i = 0; i <= H; i++)
		{

			if (Q[i].size() == 0) {
				goto G;
			}

			if (!Q[i].empty())
			{
				pair<long long, long long>R = Q[i].top();
				Q[i].pop();
				for (int j = 0; j < (int)(x[R.second].size()); j++)
				{
					if (get<0>(x[R.second][j]) == 8) {
						get<0>(x[R.second][j]) = 8;
					}

					long long p1 = get<1>(x[R.second][j]) + R.first;
					if (U[(long long)(get<3>(x[R.second][j]))] == 1LL) {
						p1 = R.first;
					}

					long long p4 = get<0>(x[R.second][j]);
					if (dist[p4][i + get<2>(x[R.second][j])] > p1)
					{
						if ((i + get<2>(x[R.second][j])) <= H) {
							dist[get<0>(x[R.second][j])][i + get<2>(x[R.second][j])] = p1;
							Q[i + get<2>(x[R.second][j])].push(make_pair(dist[get<0>(x[R.second][j])][i + get<2>(x[R.second][j]) ], get<0>(x[R.second][j])));
						}
					}
				}
			}
		G:;
		}
	}
}

void _memset() {
	N = 0; M = 0; H = 0; K = 0; S = 0; T = 0; P = 0;
	a1 = 0; a2 = 0; a3 = 0; a4 = 0; a5 = 0;
	maxn = INF;

	for (int i = 0; i < MAX_H; i++) {
		while (!Q[i].empty()) { Q[i].pop(); }
	}
	for (int i = 0; i < MAX_N; i++) {
		x[i].clear();
	}

	long long p2 = (1 << MAX_K);
	for (int i = 0; i < p2; i++) {
		dp[i] = INF;
		y[i] = 0;
		for (int j = 0; j <= MAX_K; j++) {
			v[i][j] = 0LL;
			w[j] = 0LL;
		}
	}
}

int main() {
	while (true)
	{
		_memset();
		cin >> N >> M >> H >> K;
		if (N == 0 && M == 0 && H == 0 && K == 0) {
			break;
		}

		for (int i = 0; i < M; i++) {
			cin >> a1 >> a2 >> a3 >> a4 >> a5;
			a5--;
			x[a1].push_back(make_tuple(a2, a3, a4, a5));
			x[a2].push_back(make_tuple(a1, a3, a4, a5));
		}
		cin >> S >> T;
		cin >> P;

		for (int i = 0; i < P; i++) {
			cin >> a1 >> y[i];
			for (int j = 0; j < a1; j++) {
				cin >> a2;
				a2--;
				v[i][a2] = 1;
			}
		}

		dp[0] = 0;
		for (int i = 0; i < (1 << K); i++) {
			if (dp[i] < INF)
			{
				long long p6[8] = { 0,0,0,0,0,0,0,0 };
				long long p7[8] = { 0,0,0,0,0,0,0,0 };
				for (int j = 0; j < K; j++) {
					p6[j] = (i / (1 << j)) % 2;
				}

				for (int j = 0; j < P; j++) {
					for (int k = 0; k < K; k++) {
						p7[k] = p6[k];
					}
					for (int k = 0; k < K; k++) {
						if (v[j][k] == 1) {
							p7[k] = 1;
						}
					}

					long long p8 = 0;
					for (int k = 0; k < K; k++) {
						p8 += p7[k] * (1LL << k);
					}
					dp[p8] = min(dp[p8], dp[i] + y[j]);
				}
			}
		}

		for (int i = 0; i < (1 << K); i++)
		{
			if (dp[i] < INF) {
				vector<long long>Z(K, 0LL);
				for (int j = 0; j < K; j++) {
					Z[j] = (i / (1 << j)) % 2;
				}
				long long p5 = dijkstra(Z);
				p5 += dp[i];
				maxn = min(maxn, p5);
			}
		}
		if (maxn == INF) {
			cout << "-1" << endl;
		}
		else {
			cout << maxn << endl;
		}
	}
	return 0;
}

Measured memory_bytes: 3772