#include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cassert>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define RSORT(c) sort((c).rbegin(),(c).rend())
#define CLR(a) memset((a), 0 ,sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

typedef unsigned char u8;

struct Edge {
    int station, cost, time;
    u8 company;
};

struct Ticket {
    int cost;
    u8 company;
};

struct P {
    int station, cost, time;

    bool operator >(const P& p) const {
        return cost > p.cost;
    }
};

const int MAX_TICKETS = 256;
const int MAX_TIME = 24;
#define INF 1e9

int ticket_cost[2][MAX_TICKETS];

int main() {
    int station_n, rail_n, time_limit, company_n;
    while (cin >> station_n >> rail_n >> time_limit >> company_n, station_n|rail_n|time_limit|company_n) {
        vector<vector<Edge>> E(station_n+1);
        REP(i, rail_n) {
            int a, b, c, h, r;
            cin >> a;
            cin >> b;
            cin >> c;
            cin >> h;
            cin >> r;
            u8 company = (1 << (r - 1));
            E[a].push_back({b, c, h, company});
            E[b].push_back({a, c, h, company});
        }

        int start, goal;
        cin >> start >> goal;

        fill_n((int *)ticket_cost, MAX_TICKETS*2, INF);
        ticket_cost[0][0] = 0;
        int ticket_n;
        cin >> ticket_n;
        REP(i, ticket_n) {
            int l, d;
            cin >> l >> d;
            int company = 0;
            REP(j, l) {
                int k;
                cin >> k;
                company |= (1 << (k - 1));
            }
            fill_n((int *)ticket_cost[1], MAX_TICKETS, INF);
            REP(j, MAX_TICKETS) {
                if (ticket_cost[0][j] != INF) {
                    if (ticket_cost[1][j] > ticket_cost[0][j]) {
                        ticket_cost[1][j] = ticket_cost[0][j];
                    }
                    int bought = j | company;
                    int next = ticket_cost[0][j] + d;
                    if (ticket_cost[1][bought] > next) {
                        ticket_cost[1][bought] = next;
                    }
                }
            }
            REP(j, MAX_TICKETS) {
                ticket_cost[0][j] = ticket_cost[1][j];
            }
        }

        int res = INF;

        // ??¨????????????
        REP(i, MAX_TICKETS) {
            int cost = ticket_cost[0][i];
            if (cost == INF) continue;

            vvi G(station_n+1, vi(MAX_TIME+1, INF));

            priority_queue<P, vector<P>, greater<P>> que;
            que.push({start, cost, 0});
            while (!que.empty()) {
                P p = que.top(); que.pop();
                if (p.station == goal) {
                    if (res > p.cost) {
                        res = p.cost;
                    }
                    break;
                }
                for (Edge e : E[p.station]) {
                    int time = p.time + e.time;
                    if (time <= time_limit) {
                        int cost = p.cost;
                        if (!(e.company & i)) {
                            cost += e.cost;
                        }
                        if (G[e.station][time] > cost) {
                            G[e.station][time] = cost;
                            que.push({e.station, cost, time});
                        }
                    }
                }
            }
            if (res == INF) {
                break;
            }
        }
        cout << (res == INF ? -1 : res) << endl;
    }
}

Measured memory_bytes: 1336