#include <bits/stdc++.h>
using namespace std;

string to_string(string s) { return s; }

template <class T>
string to_string(vector<T> v) {
    string ret = "{";
    for (int i = 0; i < v.size() - 1; ++i) {
        ret += to_string(v[i]) + ",";
    }
    if (v.size() > 0) {
        ret += to_string(v.back());
    }
    ret += "}";
    return ret;
}

void debug() { cerr << endl; }

template <class Head, class... Tail>
void debug(Head head, Tail... tail) {
    cerr << to_string(head) << " ";
    debug(tail...);
}

struct Edge {
    int from, to, cost, tim, com;
    Edge(int s, int t, int c, int h, int r)
        : from(s), to(t), cost(c), tim(h), com(r) {}
};

struct info {
    int nx, cost, tim;
    info(int v, int c, int h) : nx(v), cost(c), tim(h) {}
};
bool operator<(const info &a, const info &b) { return a.cost >= b.cost; }

const int INF = 1e9;
int dp[500];
int dist[500][32];
int l[500], d[500];

int main() {
    vector<int> test({-1, 0, 2, 4});
    // debug(test);
    int n, m, h, k;
    while (cin >> n >> m >> h >> k) {
        if (n == 0 && m == 0 && h == 0 && k == 0) break;
        vector<Edge> g[n];
        for (int i = 0; i < m; i++) {
            int a, b, c, hh, r;
            cin >> a >> b >> c >> hh >> r;
            g[a - 1].push_back(Edge(a - 1, b - 1, c, hh, r - 1));
            g[b - 1].push_back(Edge(b - 1, a - 1, c, hh, r - 1));
        }
        int s, t, p;
        cin >> s >> t >> p;
        s--;
        t--;
        memset(l, 0, sizeof(l));
        memset(d, 0, sizeof(d));
        fill(dp, dp + 500, INF);
        for (int i = 0; i < p; i++) {
            cin >> l[i] >> d[i];
            int setcom = 0;
            for (int j = 0; j < l[i]; j++) {
                int kk;
                cin >> kk;
                setcom |= (1 << (kk - 1));
            }
            // あるパスポートを買った時の値段
            // setcom は会社の集合
            dp[setcom] = min(dp[setcom], d[i]);
        }
        dp[0] = 0;
        for (int i = 0; i < 1 << k; i++) {
            if (dp[i] == INF) continue;
            for (int j = 0; j < 1 << k; j++) {
                dp[i | j] = min(dp[i | j], dp[i] + dp[j]);
            }
        }
        // すべての会社集合について最短経路問題を解く
        int ans = INF;
        for (int bit = 0; bit < 1 << k; bit++) {
            if (dp[bit] == INF) continue;
            // cout << bit << endl;
            priority_queue<info> que;
            que.push(info(s, 0, 0));
            int res = INF;
            for (int i = 0; i < 500; i++) {
                for (int j = 0; j < 32; j++) dist[i][j] = INF;
            }
            dist[s][0] = 0;
            while (!que.empty()) {
                info cur = que.top();
                que.pop();
                if (dist[cur.nx][cur.tim] < cur.cost) continue;
                if (cur.nx == t) {
                    res = min(res, cur.cost);
                    continue;
                }
                for (int i = 0; i < g[cur.nx].size(); i++) {
                    Edge e = g[cur.nx][i];
                    int nxh = cur.tim + e.tim;
                    if (nxh > h) continue;
                    int nxc;
                    if (bit >> e.com & 1)
                        nxc = cur.cost;
                    else
                        nxc = cur.cost + e.cost;
                    if (dist[e.to][nxh] > nxc) {
                        dist[e.to][nxh] = nxc;
                        que.push(info(e.to, nxc, nxh));
                    }
                }
            }
            ans = min(ans, res + dp[bit]);
        }
        cout << (ans == INF ? -1 : ans) << endl;
    }
    return 0;
}



Measured memory_bytes: 3212