#include <bits/stdc++.h>

using namespace std;

// #define LOG(...) fprintf(stderr, __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(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SQ(n) (n) * (n)

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;

const int INF = (int)1e9;

struct Edge {
  int to, cost, time, campany;
};

struct Passport {
  int cost, campany;
};

struct P {
  int p, cost, time;

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

int G[101][25];

int main() {
  int node_n, edge_n, max_time, campany_n;
  while(cin >> node_n >> edge_n >> max_time >> campany_n, node_n | edge_n | max_time | campany_n ) {
    vector<vector<Edge>> E(node_n + 1);
    LOG("dddddddd\n");
    REP(i, edge_n){
      int from, to, cost, time, campany;
      cin >> from >> to >> cost >> time >> campany;
      campany--;
      E[from].push_back({to, cost, time, 1 << campany});
      E[to].push_back({from, cost, time, 1 << campany});
    }
    int start, goal, passport_n;
    cin >> start >> goal >> passport_n;
    vector<Passport> pass(passport_n);
    LOG("cccccccccc\n");
    REP(i, passport_n){
      int camp_n;
      cin >> camp_n;
      cin >> pass[i].cost;
      REP(j, camp_n){
        int camp;
        cin >> camp;
        camp--;
        pass[i].campany |= (1 << camp);
      }
    }

    vi campany_cost(1<<campany_n, INF);
    campany_cost[0] = 0;
    REP(i, 1<<campany_n){
      if(campany_cost[i] == INF) continue;
      REP(j, passport_n){
        campany_cost[i|pass[j].campany] = min(campany_cost[i|pass[j].campany], campany_cost[i]+pass[j].cost);
      }
    }

    LOG("costttttt\n");
    for(int c:campany_cost){
      LOG("%d\n", c);
    }
    LOG("costttttt\n");


    int res = INF;
    LOG("bbbbbbbbb\n");
    REP(i, 1 << campany_n){
      LOG("aaaaaaaaaaaaaa\n");
      if(campany_cost[i] == INF) continue;
      fill_n((int*)G, 25 * 101, INF);
      G[start][0] = campany_cost[i];
      int free_campany = i;

      priority_queue<P, vector<P>, greater<P>> que;
      que.push({start, G[start][0], 0});
      while(!que.empty()) {
        P p = que.top(); que.pop();
        LOG(">>> p:%d  cpst:%d\n", p.p, p.cost);
        if(p.p == goal) {
          res = min(res, p.cost);
          break;
        }

        for(Edge e:E[p.p]) {
          LOG(" -- %d\n", e.to);
          int next_cost = p.cost + e.cost;
          if(e.campany & free_campany) next_cost -= e.cost;
          int next_time = p.time + e.time;
          if(next_time > max_time) continue;
          if(G[e.to][next_time] > next_cost) {
            G[e.to][next_time] = next_cost;
            LOG("p %d  cost:%d\n", e.to, next_cost);
            que.push({e.to, next_cost, next_time});
          }
        }
      }
    }

    if (res == INF) {
      cout << -1 << endl;
    }else{
      cout << res << endl;
    }
  }
}

Measured memory_bytes: 3184