#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
#define INT_MAX 4294967295;
typedef pair<int,int> P;

//howmuch[i]:i番のアイテムの最小の値段
int howmuch[100];

//itemname[i]:i番目のアイテムの名前
char itemname[100][101];

//n:アイテムの種類 m:レシピの数
int n,m;

//resipeuseditem[i][k]:iをつくるためにkを用いたかどうかの判定
bool resipeuseditem[100][100];

//resipeN[i]:iを作るために用いたアイテムの番号を保存する
queue <int> resipeN[100];

//allminseek作業用キュー
priority_queue< P,vector<P>,greater<P> > que;

//アイテム名を番号に変換する関数
int nameTOnonber(char *);

//最小値を求める
void allminseek();

int main()
{
	int k,i,j,oTOi,o2;
	char o[101];

	scanf("%d",&n);

	while(n != 0){
	//初期化
	for(i = 0; i < 100; i++){
		for(j = 0; j < 100; j++){
			resipeuseditem[i][j] = false;
		}
	}

	//入力
	for(i = 0;i < n; i++){
		fflush(stdin);
		scanf("%s %d",itemname[i],&howmuch[i]);
		int a = nameTOnonber(itemname[i]);
		que.push(P(howmuch[i],a));
	}

	scanf("%d",&m);
	for(i = 0;i < m; i++){
		scanf("%s %d",o,&k);
		oTOi = nameTOnonber(o);
		//printf("k:%d\n",k);
		for(j = 0; j < k; j++){
			scanf("%s",o);
			o2 = nameTOnonber(o);
			resipeN[oTOi].push(o2);
			resipeuseditem[oTOi][o2] = true;
			//printf("作るもの:%d 素材[%d]:%d\n",oTOi,j,o2);
		}
		//printf("size:%d\n",resipeN[oTOi].size());
	}
	
	//探索
	allminseek();

	scanf("%s",o);
	printf("%d\n",howmuch[ nameTOnonber(o) ]);

	scanf("%d",&n);
	}
	return 0;
}

int nameTOnonber(char *name){
	for(int i = 0; i < n; i++){
		if(strcmp(itemname[i],name) == 0){
			//printf("アイテム名:%s 配列番号:%d\n",name,i);
			return i;
		}
	}

	printf("nameTOnonber変換ミス\n");
	return INT_MAX;
}

void allminseek(){

	//アイテムiを使用したかどうかのフラグ
	bool used[100];
	int temp,minNO;

	//printf("min:配列%d 値段%d",min.first,min.second);
	for(int i = 0; i < n; i++)	used[i] = false;

	while(!que.empty()){
		minNO = que.top().second;
		que.pop();
		//printf("最小値段アイテム:%s\n",itemname[minNO]);
		if(!used[ minNO ]){
			//minNOを使用しているレシピの探索と実行
			for(int i = 0;i < n; i++){
				//printf("[%d][%d]%d\n",i,minNO,resipeuseditem[i][minNO]);
				if(resipeuseditem[i][minNO]){
					temp = 0;
					for(int j = 0; j < resipeN[i].size(); j++){
						temp += howmuch[ resipeN[i].front() ];
						//printf("材料:%d 値段:%d 合計:%d\n",resipeN[i].front(),howmuch[ resipeN[i].front() ],temp);
						resipeN[i].push(resipeN[i].front());
						resipeN[i].pop();
					}
					if(howmuch[i] > temp){
						howmuch[i] = temp;
						que.push(P(temp,i));
					}
				}
			}
			
			used[ minNO ] = true;
		}
	}
}