#include <bits/stdc++.h>
#define rep(i,a,n) for(int i=a; i<n; i++)
using namespace std;
typedef pair<int, int> pii;

struct Edge {
    int to, cost, time, company;
    Edge(int b, int c, int h, int r) :
        to(b), cost(c), time(h), company(r) {}
};

struct Elem {
    int point, cost, time;
    Elem(int p, int c, int t) : 
        point(p), cost(c), time(t) {}
};
bool operator>(const Elem &a, const Elem &b) {
    return a.cost != b.cost ? a.cost > b.cost : a.time > b.time;
}

typedef vector< vector<Edge> > Graph;

const int MAXN = 110;
const int MAXH = 30;
const int SIZE = 1000;
const int INF = (int)1e9;

int N, M, H, K, S, T, P;
int dp[SIZE][SIZE], rec[MAXN][MAXH];
int main() {
    while(cin >> N >> M >> H >> K, N||M||H||K) {
        Graph G(N);
        rep(i,0,M) {
            int a, b, c, h, r;
            cin >> a >> b >> c >> h >> r;
            a--; b--; r--;
            G[a].push_back(Edge(b, c, h, r));
            G[b].push_back(Edge(a, c, h, r));
        }

        cin >> S >> T >> P;
        S--; T--;
        vector<pii> ticket;
        rep(i,0,P) {
            int l, d; cin >> l >> d;
            int idx = 0;
            rep(j,0,l) {
                int k; cin >> k; k--;
                idx += (1 << k);
            }
            ticket.push_back(pii(idx, d));
            // printf("variety: %d\n", idx);
        }

        rep(i,0,SIZE) rep(j,0,SIZE) dp[i][j] = INF;
        dp[0][0] = 0;
        rep(i,0,P) {
            rep(bit,0,(1<<K)) {
                dp[i+1][bit] = min(dp[i+1][bit], dp[i][bit]);
                int variety = ticket[i].first;
                int cost = ticket[i].second;
                int nbit = variety | bit;
                dp[i+1][nbit] = min(dp[i+1][nbit], dp[i][bit] + cost);
            }
        }

        int mi = INF;
        rep(bit,0,(1<<K)) {
            if(dp[P][bit] == INF) continue;
            // printf("dp[P][%d] = %d\n", bit, dp[P][bit]);
            rep(i,0,MAXN) rep(j,0,MAXH) rec[i][j] = INF;
            rec[S][0] = dp[P][bit];
            // point, cost, time
            priority_queue< Elem, vector<Elem>, greater<Elem> > q;
            q.push(Elem(S, dp[P][bit], 0));

            while(!q.empty()) {
                Elem pick = q.top(); q.pop();
                int from = pick.point, money = pick.cost, time = pick.time;
                // printf("pick: from = %d, money = %d, time = %d\n", from, money, time);
                for(auto x : G[from]) {
                    int nt = time + x.time, cost;
                    if(nt > H) continue;
                    if(bit >> x.company & 1) cost = 0;
                    else cost = x.cost;
                    // printf("rec[%d][%d] = %d, candidate = %d\n", x.to, nt, rec[x.to][nt], money+cost);
                    if(rec[x.to][nt] > money + cost) {
                        rec[x.to][nt] = money + cost;
                        q.push(Elem(x.to, money + cost, nt));
                    }
                }
            }

            rep(i,0,H+1) {
                // printf("rec[T][%d] = %d\n", i, rec[T][i]);
                mi = min(mi, rec[T][i]);
            }
        }
        if(mi != INF) cout << mi << endl;
        else cout << -1 << endl;
    }
    return 0;
}