#include <cstdio>
#include <queue>
#include <algorithm>

#define rep(i, n) for(int i = 0; i < (n); ++i)

using namespace std;

const int inf = 2e6;

typedef pair<int, int> P;

struct E{
	E(int t, int c, int r): t(t), c(c), r(r){}

	int t, c, r;
};

int n, m, h, k;
vector<E> g[2500];
int s, t, p;
int f[256][257];
int d[2500];

int index(int i, int j){
	return i * (h + 1) + j;
}

int main(){
	while(scanf("%d%d%d%d", &n, &m, &h, &k), n){
		rep(i, m){
			int a, b, c, d, e;
			scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
			--a;
			--b;
			--e;
			rep(i, h - d + 1){
				g[index(a, i)].push_back(E(index(b, i + d), c, e));
				g[index(b, i)].push_back(E(index(a, i + d), c, e));
			}
		}
		scanf("%d%d%d", &s, &t, &p);
		--s;
		--t;
		fill_n(f[0], 1 << k, inf);
		f[0][0] = 0;
		rep(i, p){
			int l, d;
			scanf("%d%d", &l, &d);
			int a = 0;
			rep(j, l){
				int k;
				scanf("%d", &k);
				a |= 1 << (k - 1);
			}
			rep(j, 1 << k){
				f[i + 1][j] = min(f[i][j & ~a] + d, f[i][j]);
			}
		}

		int ans = inf;
		rep(i, 1 << k){
			if(f[p][i] == inf){
				continue;
			}

			fill_n(d, index(n, 0), inf);

			priority_queue<P, vector<P>, greater<P> > q;
			d[index(s, 0)] = 0;
			q.push(P(0, index(s, 0)));
			while(!q.empty()){
				P v = q.top();
				q.pop();
				if(v.first > d[v.second]){
					continue;
				}
				rep(j, g[v.second].size()){
					E e = g[v.second][j];
					if(i & (1 << e.r)){
						e.c = 0;
					}
					if(d[e.t] > v.first + e.c){
						d[e.t] = v.first + e.c;
						q.push(P(d[e.t], e.t));
					}
				}
			}

			int a = *min_element(d + index(t, 0), d + index(t + 1, 0));
			if(a != inf){
				ans = min(f[p][i] + a, ans);
			}
		}
		printf("%d\n", ans != inf ? ans : -1);

		rep(i, index(n, 0)){
			g[i].clear();
		}
	}
	return 0;
}