import std.stdio;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

struct Edge {
    int a, b, c, h, r;
}
 
int N, M, H, K;
Edge[] G[100];
int S, T;
int P;
int Pass[256];
const INF = int.max / 4;

bool input() {
    scanf("%d %d %d %d\n", &N, &M, &H, &K);
    if (N == 0 && M == 0 && H == 0 && K == 0) return false;
    foreach (i; 0 .. N) G[i].clear;
    foreach (i; 0 .. M) {
        int a, b, c, h, r;
        scanf("%d %d %d %d %d\n", &a, &b, &c, &h, &r);
        a--; b--; r--;
        G[a] ~= Edge(a, b, c, h, r);
        G[b] ~= Edge(b, a, c, h, r);
    }
    scanf("%d %d\n", &S, &T);
    S--; T--;
    scanf("%d\n", &P);
    Pass[] = INF;
    foreach (i; 0 .. P) {
        int l, d; scanf("%d %d\n", &l, &d);
        int bit = 0;
        foreach (j; 0 .. l) {
            int k;
            scanf("%d", &k);
            k--;
            bit |= (1 << k);
        }
        Pass[bit] = d;
    }
    return true;
}

void solve() {
    void initPass() {
        Pass[0] = 0;
        foreach (i; 0 .. (1<<K)) {
            foreach (j; i + 1 .. (1<<K)) {
                Pass[i | j] = min(Pass[i | j], Pass[i] + Pass[j]);
            }
        }
    }
    initPass;
    struct State {
        int a, h, c;
    }
    const int MaxN = 100;
    const int MaxH = 24;
    bool Time() {
        static int D[MaxN];
        D[] = INF;
        D[S] = 0;
        BinaryHeap!(Array!State, "a.h > b.h") PQ;
        PQ.insert(State(S, 0, 0));
        while (!PQ.empty) {
            State cur = PQ.front; PQ.removeFront;
            foreach (edge; G[cur.a]) {
                int next_h = cur.h + edge.h;
                if (D[edge.b] > next_h) {
                    D[edge.b] = next_h;
                    PQ.insert(State(edge.b, next_h, cur.c + edge.c));
                }
            }
        }
        return D[T] <= H;
    }

    if (!Time) {
        writeln(-1);
        return;
    }

    int Cost(int bit) {
        static int D[MaxN][MaxH + 1];
        foreach (i; 0 .. N) D[i][] = -1;
        int dfs(int v, int h) {
            if (h > H) return INF;
            if (v == T) return 0;
            if (D[v][h] >= 0) return D[v][h];
            int Ret = INF;
            foreach (edge; G[v]) {
                int next_h = h + edge.h;
                int cost = ((bit & (1 << edge.r)) ? 0 : edge.c);
                Ret = min(Ret, cost + dfs(edge.b, next_h));
            }
            return D[v][h] = Ret;
        }
        return dfs(S, 0);
    }

    int Ans = INF;
    foreach (bit; 0 .. (1<<K)) {
        if (Pass[bit] == INF) continue;
        Ans = min(Ans, Cost(bit) + Pass[bit]);
    }
    writeln(Ans);
}

void main() {
    while (input) solve;
}