#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

//改造
typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0 //デバッグする時1にしてね
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//ここから編集する
class Dijkstra {
public:
    using T = long long int;
    typedef pair<T, int> P; //firstは最短距離、secondは頂点の番号
    const T inf = (T) 5e15;
    struct edge {
        int to;
        T cost;
    };

    int V;                  //超点数
    vector<vector<edge>> G; //グラフ,G[i]はiから出る辺の集合,G[i][j]はiから出る辺のj番目の辺
    vector<T> d;           //最短距離

    //0origin
    Dijkstra(int N) {
        V = N;
        G = vector<vector<edge >>(N);
        d = vector<T>(N);
    };

    void dijkstra(int s) {
        priority_queue<P, vector<P>, greater<P>> que;
        fill(d.begin(), d.end(), inf);
        d[s] = 0;
        que.push(P(0, s));

        while (!que.empty()) {
            P p = que.top();
            que.pop();
            int v = p.second;
            if (d[v] < p.first)
                continue;
            for (int i = 0; i < G[v].size(); i++) {
                edge e = G[v][i];
                if (d[e.to] > d[v] + e.cost && !(d[e.to] == inf && d[v] == inf)) {
                    d[e.to] = d[v] + e.cost;
                    que.push(P(d[e.to], e.to));
                }
            }
        }
    }

    /* 頂点fromに頂点toに達するコストcostの辺を貼る */
    void addEdge(int from, int to, T cost) {
        edge e;
        e.to = to;
        e.cost = cost;
        G[from].push_back(e);
    }

    T getDist(int v) {
        return d[v];
    }
};

class Solve {
public:
    int N, M, H, K;
    vector<ll> a, b, c, h, r;
    int S, T;
    int P;
    vector<ll> d;
    vector<vector<int>> k;

    vector<ll> oneday;

    ll dfs(int bit) {
        if (bit == 0) return 0ll;
        for (int i = 1; i < bit; ++i) {
            for (int j = 1; j < bit; ++j) {
                if ((i | j) == bit) {
//                    ll tmp = dfs(i) | dfs(j);
                    ll tmp = oneday[i] + oneday[j];
                    chmin(oneday[bit], tmp);
                }
            }
        }

        return oneday[bit];
    }

    void subset() {
        for (int bit = (1 << K) - 1; bit > 0; --bit) {
            if (oneday[bit] == INFl) continue;
            int sub = bit;
            do {
                chmin(oneday[sub], oneday[bit]);
                sub = (sub - 1) & bit;
            } while (sub != bit);
        }
    }

    ll func(int bit) {
//        ll ret = oneday[bit];
        if (oneday[bit] == INFl) return INFl;

        auto conv = [&](int v, int hh) {
            return hh * N + v;
        };

        Dijkstra dij(N * (H + 1));

        for (int i = 0; i < M; ++i) {
            int from = a[i];
            int to = b[i];
            int cost = c[i];
            if (bit >> r[i] & 1) cost = 0;

            for (int st = 0; st <= H; ++st) {
                if (st + h[i] <= H) {
                    int f = conv(from, st);
                    int t = conv(to, st + h[i]);
//                    cerr << f << " " << t << endl;
                    dij.addEdge(f, t, cost);

                    f = conv(from, st + h[i]);
                    t = conv(to, st);
                    dij.addEdge(t, f, cost);
                }
            }
        }

        int s = conv(S, 0);
        dij.dijkstra(s);
        ll min_cost = INFl;
        for (int hh = 0; hh <= H; ++hh) {
            int to = conv(T, hh);
            chmin(min_cost, dij.getDist(to));
        }

        if (min_cost == INFl) return INFl;
        return min_cost + oneday[bit];


    }


    bool solve() {
        cin >> N >> M >> H >> K;
        if (N == 0) return false;
        a.resize(M);
        b.resize(M);
        c.resize(M);
        h.resize(M);
        r.resize(M);
        rep(i, 0, M) {
            cin >> a[i] >> b[i] >> c[i] >> h[i] >> r[i];
            a[i]--;
            b[i]--;
            r[i]--;
        }
        cin >> S >> T;
        S--, T--;

        cin >> P;
        d.resize(P);
        k.resize(P);
        oneday.resize(1 << K, INFl);
        oneday[0] = 0;


        for (int i = 0; i < P; ++i) {
            int l;
            cin >> l >> d[i];
            for (int j = 0; j < l; ++j) {
                int tmp;
                cin >> tmp;
                tmp--;
                k[i].push_back(tmp);
            }
        }

        for (int i = 0; i < P; ++i) {
            int bit = 0;
            for (int j = 0; j < k[i].size(); ++j) {
                bit |= (1 << k[i][j]);
            }
            chmin(oneday[bit], d[i]);
        }

        subset();
        for (int bit = 1; bit < 1 << K; ++bit) {
            if (bit == 7) {
                int tapi = 1333;
            }
            dfs(bit);
        }

        ll ans = INFl;
        for (int bit = 0; bit < 1 << K; ++bit) {
            chmin(ans, func(bit));
        }
        if (ans == INFl) {
            cout << -1 << endl;
        } else {
            cout << ans << endl;
        }


        return true;
    }
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    int cnt = 0;
    while (Solve().solve()) {
//        cerr << (cnt++) << endl;

    }

    return 0;
}



Measured memory_bytes: 3724