#include <vector>
#include <iostream>
#include <queue>
#include <bitset>

using namespace std;

#define INF 1<<30

typedef pair<int, int>Pa;
typedef pair<Pa, int>PP;
struct Edge{
  int to;
  int cost;
  int h;
  int r;
  Edge(int a, int b, int c, int d){
    to = a;
    cost = b;
    h = c;
    r = d;
  }
};

vector<Edge>G[128];
int N, M, H, K;
int S, T;
int P;
int dis[256][128][25];
int deals[256];
int bits[256];
int dp[256][256];


void dfs(int p, int bitmap){
  for(int i=0;i<256;i++) for(int j=0;j<256;j++) dp[i][j] = INF;
  dp[0][0] = 0;
  for(int i=0;i<(1<<K);i++){
    for(int j=0;j<P;j++){
      dp[j+1][i|bits[j]] = min(dp[j+1][i|bits[j]], dp[j][i] + deals[j]);
      dp[j+1][i] = min(dp[j+1][i], dp[j][i]);
      //      cout << j+1 << " " << static_cast<bitset<8> >(i|bits[j]) << " " << dp[j+1][i|bits[j]] << endl;
    }
  }
  //  for(int i=0;i<(1<<K);i++){
  //    cout << static_cast<bitset<8> >(i) << " " << dp[P][i] << endl;
  //  }
}

void dijkstra(int bitmap, int s){
  int (*dist)[25] = dis[bitmap];
  //  fill(dist, dist + 128*25, INF);
  for(int i=0;i<128;i++) for(int j=0;j<25;j++) dist[i][j] = INF;
  priority_queue<PP, vector<PP>, greater<PP> >PQ;
  PQ.push(PP(Pa(0, s), 0));
  dist[s][0] = 0;
  while(!PQ.empty()){
    PP q = PQ.top(); PQ.pop();
    int d = q.first.first;
    int p = q.first.second;
    int h = q.second;
    if(dist[p][h] < d) continue;
    //    cout << static_cast<bitset<8> >(bitmap) << " " << p << " " << d << endl;    
    for(int i=0;i<G[p].size();i++){
      Edge next = G[p][i];
      int cost = next.cost;
      if(bitmap & 1<<next.r) cost = 0;
      if(h+next.h <= H && dist[p][h] + cost < dist[next.to][h+next.h]){
	dist[next.to][h+next.h] = dist[p][h] + cost;
	PQ.push(PP(Pa(dist[next.to][h+next.h], next.to), h + next.h));
      }
    }
  }
}

int solve(){
  dfs(0, 0);
  
  for(int i=0;i<(1<<K);i++){
    dijkstra(i, S);    
  }

  int ret = INF;
  for(int i=0;i<(1<<K);i++){
    //    cout << static_cast<bitset<8> >(i) << " " << dp[P][i] << " " << dis[i][T] << endl;
    //    int d = INF;
    //    for(int j=0;j<=P;j++) d = min(d, dp[j][i]);
    //    if(d == INF || dis[i][T] == INF) continue;
    //    ret = min(ret, d + dis[i][T]);
    int dist = INF;
    for(int j=0;j<=H;j++) dist = min(dist, dis[i][T][j]);
    if(dp[P][i] == INF || dist == INF) continue;
    ret = min(ret, dp[P][i] + dist);
    //    if(dp[P][i] == INF || dis[i][T] == INF) continue;
    //    ret = min(ret, dp[P][i] + dis[i][T]);
  }
  if(ret == INF) return -1;
  return ret;
}

int main(){
  while(1){
    for(int i=0;i<128;i++) G[i].clear();
    cin >> N >> M >> H >> K;
    if(!(N || M || H || K)) break;
    for(int i=0;i<M;i++){
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r; a--; b--; r--;
      G[a].push_back(Edge(b, c, h, r));
      G[b].push_back(Edge(a, c, h, r));
    }
    cin >> S >> T >> P; S--; T--;
    for(int i=0;i<P;i++){
      int l, d;
      cin >> l >> deals[i];
      int bit = 0;
      for(int j=0;j<l;j++){
	int k; cin >> k; k--;
	bit |= 1<<k;
      }
      bits[i] = bit;
    }

    cout << solve() << endl;
  }
  return 0;
}