Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"log"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

func main() {
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		having := map[string]Entry{}
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			name := buf[0]
			price, _ := strconv.Atoi(buf[1])
			having[name] = Entry{price, []string{}}
		}
		scanner.Scan()
		m, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < m; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			name_, price_ := buf_[0], INF
			if _, ok := having[name_]; ok {
				price_ = having[name_].price
			}
			having[name_] = Entry{price_, buf_[2:]}
		}
		scanner.Scan()
		fmt.Println(calculation(scanner.Text(), having))
		log.Printf("%+v\n", having)
	}
}

type Entry struct {
	price int
	elements []string
}

// メモ再帰的
func calculation(target string, having map[string]Entry) int {
	ans := INF
	if len(having[target].elements) > 0 {
		ans = 0
		for _, item := range having[target].elements {
			ans += calculation(item, having)
		}
	}
	return min(ans, having[target].price)
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

C++: #include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pll> pip;
const ll INF = 1ll<<57;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

int N, M;
ll cost[200];
string S[100], O[100], Q[100][100], T;
int P[100], K[100];
vector<int> g[100];

int main() {
	while (cin >> N, N) {
		REP(i, N) cin >> S[i] >> P[i];
		cin >> M;
		REP(i, M) {
			cin >> O[i] >> K[i];
			REP(j, K[i]) cin >> Q[i][j];
		}
		cin >> T;
		
		map<string, int> conv;
		REP(i, N) conv[S[i]] = conv.size() - 1;
		REP(i, M) {
			if (conv.find(O[i]) == conv.end()) conv[O[i]] = conv.size() - 1;
			REP(j, K[i]) if (conv.find(Q[i][j]) == conv.end()) conv[Q[i][j]] = conv.size() - 1;
		}
		
		REP(i, M) {
			g[i].push_back(conv[O[i]]);
			REP(j, K[i]) g[i].push_back(conv[Q[i][j]]);
		}
		
		fill(cost, cost + 200, INF);
		REP(i, N) chmin(cost[conv[S[i]]], P[i]);
		
		while (true) {
			bool update = false;
			REP(i, M) {
				ll sum = 0;
				FOR(j, 1, g[i].size()) sum += cost[g[i][j]];
				update |= chmin(cost[g[i][0]], sum);
			}
			if (!update) break;
		}
		
		cout << cost[conv[T]] << endl;
	}
	return 0;
}

C++: 
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;

int dfs(string key);

map<string,int> mny;
map<string,vector<string> > rsp;

int main(){
	int n,m;
	string na;
	while(1){
		mny.clear();
		rsp.clear();
		cin >> n;
		if(n == 0) break;
		for(int i=0;i<n;i++){
			int mo;
			cin >> na >> mo;
			mny[na] = mo;
		}
		cin >> m;
		for(int i=0;i<m;i++){
			int k;
			cin >> na >> k;
			string str;
			for(int j=0;j<k;j++){
				cin >> str;
				rsp[na].push_back(str);
			}
		}
		cin >> na;
		cout << dfs(na) << endl;
	}
}

int dfs(string key){
	int rec=0;
	if(rsp[key].size()){
		int len = rsp[key].size();
		for(int i=0;i<len;i++){
			rec += dfs(rsp[key][i]);
		}
	}
	else {
		rec = mny[key];
	}
	if(mny[key] < rec) rec = mny[key];
	return rec;
}

C++: #include<iostream>
#include<vector>
#include<string>
#include <map>
using namespace std;
pair<string, int>p[101];
pair<string, vector<string> >chan[101];
int search(string);
int n;
int m,si;
int main()
{
	
	while (true){
		cin >> n;
		if (n == 0){
			break;
		}
		for (int i = 0; i < n; i++){
			cin >> p[i].first >> p[i].second;
		}

		cin >> m;
		for (int i = 0; i < m; i++){
			cin >> chan[i].first >> si;
			for (int i2 = 0; i2 < si; i2++){
				string s;
				cin >> s;
				chan[i].second.push_back(s);
			}
		}
		string s;
		cin >> s;
		int ans = search(s);
		cout << ans << endl;
	}
}
int search(string s){
	int num = 0;
	bool flag = true;
	for (int i = 0; i < m; i++){
		if (chan[i].first == s){
			flag = false;
			for (int i2 = 0; i2 < chan[i].second.size(); i2++){
				num += search(chan[i].second[i2]);
			}
		}
	}
	if (flag){
		for (int i = 0; i < n; i++){
			if (p[i].first == s){
				num += p[i].second;
			}
		}
	}
	return num;
}

C++: #include "bits/stdc++.h"

#define REP(i,num) for(int i=0;i<(num);++i)
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=int>
T in(){T x; cin >> x; return (x);}
template<typename T=int,typename C=vector<T>>
C vecin(int N){C x(N);REP(i,N){x[i]=in<T>();}return move(x);}

void vout(){cout << endl;}
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){cout << ' ' << h;vout(forward<Tail>(t)...);}
void out(){cout << endl;}
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){cout << h;vout(forward<Tail>(t)...);}

class Data{
public:
	string name;
	int value,new_value{0};
};

class ConnectNodeInfo{
	vector<vector<pair<ll,ll>>> graph;
public:
	ConnectNodeInfo(int node_num){
		graph.resize(node_num);
	}
	void AddNonDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
		graph[v].emplace_back(u,w);
	}
	void AddDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
	}
	vector<pair<ll,ll>>& operator[](ll index){
		return graph[index];
	}
	size_t size(){return graph.size();}
};

int DFS(ConnectNodeInfo& connect,int parent,int child,vector<Data>& D){
	int sum=0;
	if(connect[child].empty()) return D[child].value;

	for(auto& x:connect[child]){
		sum += DFS(connect,child,x.first,D);
	}
	D[child].value = min(D[child].value,sum);
	return D[child].value;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	while(true){
		int N=in();
		if(!N) break;
		vector<Data> D(N);
		map<string,int> E;
		REP(i,N){
			D[i].name=in<string>();
			D[i].value=in();
			E.emplace(D[i].name,i);
		}
		int M=in();
		ConnectNodeInfo connect(N),connect_inv(N);
		REP(i,M){
			string S=in<string>();
			int K=in();
			REP(j,K){
				string T=in<string>();
				connect.AddDirectionalConnection(E[S],E[T],1);
				connect_inv.AddDirectionalConnection(E[T],E[S],1);
			}
		}
		vector<int> L;
		REP(i,N){
			if(connect_inv[i].empty()) L.push_back(i);
		}
		for(auto& x:L){
			DFS(connect,-1,x,D);
		}
		out(D[E[in<string>()]].value);
	}

	return 0;
}