You are a hero of a role playing game, asked by the king to defeat monsters threating people’s life.

You have been making a long journey with your colleagues, and you are now in the town closest to the final dungeon where the head of monsters dwells. You have heard from people that the head monster hits with his strong arms, casts powerful spells, and has many special abilities, and your party would be easily killed off without powerful equipments due to severe damages. Thus you need to prepare the equipments.

On the other hand, you have a number of magical spheres collected during the journey. Those spheres are not useful themselves, but they can be turned into special items by a spell of reaction. You can obtain some amount of money by selling those special items to shops in the town, then buy the equipments by that money.

The spell of reaction works as follows. Each sphere has a color, and either positive attribute or negative attribute. You choose one sphere with positive attribute and another with negative attribute, and you cast the spell to the two spheres. Then the spheres will make reaction to have a set of special items produced. Those spheres will disappear after the reaction. The set of items you will obtain solely depends on the colors of the two spheres. You can cast the spell as many as you want, but of course you cannot cast the spell to spheres that have disappeared. Also, not all pairs of colors of spheres make reaction.

It is natural that you want to obtain money as much as possible. So you should choose carefully the pairs of spheres before casting the spell. On the other hand, you should be an excellent programmer, so it should be an easy task to write a program that finds the best way using your computer.

Your task is now clear - write a program and get ready for the battle with the head monster!



Input

The input is a sequence of datasets. Each dataset is formatted as follows:


N- N+
Number of available spheres
Definition of items
Definition of reactions


The first line contains two integers N- and N+, which are the numbers of different colors of spheres with negative and positive attributes, respectively. The rest of the dataset is divided into three parts.

The first part describes the number of available spheres. This part has the following format:


K1- K2- ... KN--
K1+ K2+ ... KN++


Ki- is the number of spheres of the i-th color with negative attribute, and Ki+ is the number of spheres of the i-th color with positive attribute.

The second part contains the definition of items. This part is formatted as follows:


M
A1 P1
...
AM PM


Here, M is the number of items that can be produced. Each of the following M lines contains a string Ai and an integer Pi, which are the name and the selling price of the i-th item respectively.

The last part gives the details of reactions. This part has the following format:


L
I1- I1+ NJ1 J1,1 ... J1,NJ1
...
IL- IL+ NJL JL,1 ... JL,NJL


The first line contains an integer L, which is the number of pairs of colors of spheres that can make reaction. Each of the next L lines starts with two integers Ii- and Ii+, which denote the colors of negative and positive spheres respectively. The next integer NJi is the number of items produced by reaction between spheres Ii- and Ii+. The line is then followed by NJi strings, each of which is an item name.

You may assume all the following: 1 ≤ N-, N+ ≤ 100; 1 ≤ Ki-, Ki+ ≤ 100; 1 ≤ M ≤ 100; 1 ≤ Pi ≤ 100; 1 ≤ L ≤ 100; 1 ≤ NJi ≤ 10. You may also assume that an item name consists only of alphanumeric characters and the length of the name does not exceed ten.

The end of input is represented by a line with two zeros. This line is not part of any dataset.

Output

For each dataset, print a line that contains the maximum possible total selling price.

Example

Input

2 2
1 1
1 1
4
A 10
B 20
C 30
D 40
4
1 1 3 A A A
1 2 2 B C
2 1 1 D
2 2 3 A A B
2 2
1 2
2 1
3
Scroll 50
Bastard 100
Heal100 10
3
1 1 1 Scroll
2 1 1 Bastard
2 2 1 Heal100
0 0


Output

90
200
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define rep(i, n) for(int i = 0; i < (n); ++i)
#define pb  push_back

const int INF = 1001001001;
const int N = 110, MAX_V = 2 * N;
const int src = 210, sink = 211;

typedef pair<int, int> P;

struct Edge { int to, cap, cost, rev; };

int h[MAX_V];   // potential
vector<Edge> G[MAX_V];

void add_edge(int from, int to, int cap, int cost)
{
    G[from].pb((Edge){ to, cap, cost, (int)G[to].size() });
    G[to].pb((Edge){ from, 0, -cost, (int)G[from].size()-1 });
}

int min_cost_flow()
{
    int res = 0;
    int dist[MAX_V], prevv[MAX_V], preve[MAX_V];
    bool first = true;
    
    while(true)
    {
        priority_queue<P, vector<P>, greater<P> > que;
        fill_n(dist, MAX_V, INF);
        dist[src] = 0;
        que.push(P(0, src));
        
        // dijkstra
        while(!que.empty())
        {
            P p = que.top(); que.pop();
            int v = p.second;
            if(dist[v] < p.first) continue;
            rep(i, G[v].size())
            {
                Edge &e = G[v][i];
                if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
                    dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                    prevv[e.to] = v; preve[e.to] = i;
                    que.push(P(dist[e.to], e.to));
                }
            }
        }
        
        if(!first) rep(v, MAX_V) h[v] += dist[v];
        first = false;
        if(h[sink] >= 0) return res;
        
        int f = INF;
        for(int v = sink; v != src; v = prevv[v])
            f = min(f, G[prevv[v]][preve[v]].cap);
        res -= f * h[sink];
        for(int v = sink; v != src; v = prevv[v]) {
            Edge &e = G[prevv[v]][preve[v]];
            e.cap -= f;
            G[v][e.rev].cap += f;
        }
    }
}

int main()
{
    int Nn, Np, Kn[N], Kp[N], M, P, L, In, Ip, NJ;
    string A, J;
    
    while(cin >> Nn >> Np && Nn)
    {
        map<string, int> table;
        fill_n(h, MAX_V, 0);
        rep(i, MAX_V) G[i].clear();
        
        rep(i, Nn) cin >> Kn[i], add_edge(src, i, Kn[i], 0);
        rep(i, Np) cin >> Kp[i], add_edge(Nn+i, sink, Kp[i], 0);
        cin >> M;
        rep(i, M) cin >> A >> P, table[A] = P;
        cin >> L; int vmax = 0;
        rep(i, L) {
            int v = 0;
            cin >> In >> Ip >> NJ;
            rep(j, NJ) cin >> J, v += table[J];
            add_edge(In-1, Nn+Ip-1, INF, -v);   // reverse sign of cost
            h[Nn+Ip-1] = min(h[Nn+Ip-1], -v);
            vmax = max(vmax, v);
        }
        
        h[sink] = -vmax;
        cout << min_cost_flow() << endl;
    }
}