/*
 * 2585.cc: 1 Day Passport
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 100;
const int MAX_M = 500;
const int MAX_H = 24;
const int MAX_K = 8;
const int KBITS = 1 << MAX_K;

const int INF = 1 << 29;

/* typedef */

struct Edge {
  int i, c, h, r;
  Edge() {}
  Edge(int _i, int _c, int _h, int _r): i(_i), c(_c), h(_h), r(_r) {}
};

typedef vector<Edge> ve;

struct Stat {
  int d, i, h;
  Stat() {}
  Stat(int _d, int _i, int _h): d(_d), i(_i), h(_h) {}
  bool operator<(const Stat &s) const { return d > s.d; }
};

/* global variables */

ve nbrs[MAX_N];
int dists[MAX_N][MAX_H + 1];
int mds[KBITS], pbs[KBITS], ds[KBITS], dp[2][KBITS];

/* subroutines */

int mindist(int n, int h, int st, int gl, int p) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= h; j++) dists[i][j] = INF;
  dists[st][0] = 0;

  priority_queue<Stat> q;
  q.push(Stat(0, st, 0));

  while (! q.empty()) {
    Stat u = q.top(); q.pop();
    if (dists[u.i][u.h] != u.d) continue;
    if (u.i == gl) continue;

    ve &nbru = nbrs[u.i];
    for (ve::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
      int &vi = vit->i, vh = u.h + vit->h;
      if (vh > h) continue;
      int vd = u.d + ((p & (1 << vit->r)) ? 0 : vit->c);
      if (dists[vi][vh] > vd) {
	dists[vi][vh] = vd;
	q.push(Stat(vd, vi, vh));
      }
    }
  }

  int mind = INF;
  for (int i = 0; i <= h; i++)
    if (mind > dists[gl][i]) mind = dists[gl][i];

  return mind;
}

/* main */

int main() {
  for (;;) {
    int n, m, h, k;
    cin >> n >> m >> h >> k;
    if (n == 0) break;

    for (int i = 0; i < n; i++) nbrs[i].clear();

    for (int i = 0; i < m; i++) {
      int ai, bi, ci, hi, ri;
      cin >> ai >> bi >> ci >> hi >> ri;
      ai--, bi--, ri--;
      nbrs[ai].push_back(Edge(bi, ci, hi, ri));
      nbrs[bi].push_back(Edge(ai, ci, hi, ri));
    }

    int st, gl;
    cin >> st >> gl;
    st--, gl--;

    int pn;
    cin >> pn;

    for (int i = 0; i < pn; i++) {
      int li;
      cin >> li >> ds[i];

      pbs[i] = 0;
      for (int j = 0; j < li; j++) {
	int kj;
	cin >> kj;
	kj--;
	pbs[i] |= (1 << kj);
      }
    }
      
    int kbits = 1 << k;
    for (int bits = 0; bits < kbits; bits++)
      mds[bits] = mindist(n, h, st, gl, bits);

    for (int bits = 0; bits < kbits; bits++) dp[0][bits] = INF;
    dp[0][0] = 0;
    int cur = 0, nxt = 1;

    for (int i = 0; i < pn; i++) {
      int &pbi = pbs[i], &di = ds[i];
      //printf("i=%d: pbi=%d, di=%d\n", i, pbi, di);
      memcpy(dp[nxt], dp[cur], sizeof(dp[cur]));
      for (int bits = 0; bits < kbits; bits++)
	if (dp[cur][bits] < INF) {
	  int bits0 = bits | pbi;
	  int dp0 = dp[cur][bits] + di;
	  if (dp[nxt][bits0] > dp0) dp[nxt][bits0] = dp0;
	}

      cur ^= 1, nxt ^= 1;
    }

    int mind = INF;
    for (int bits = 0; bits < kbits; bits++)
      if (dp[cur][bits] < INF && mds[bits] < INF) {
	//printf("%d: %d, %d\n", bits, dp[cur][bits], mds[bits]);
	int d = dp[cur][bits] + mds[bits];
	if (mind > d) mind = d;
      }

    printf("%d\n", (mind >= INF) ? -1 : mind);
  }

  return 0;
}

Measured memory_bytes: 1328