# Aizu Problem 0201: Wrought Gold Master
#
import sys, math, os

# read input:
PYDEV = os.environ.get('PYDEV')
if PYDEV=="True":
    sys.stdin = open("sample-input.txt", "rt")

class DirectedGraph():
    def __init__(self):
        self.edges = {}

    def AddNode(self, node):
        if node not in self.edges:
            self.edges[node] = []

    def GetNodes(self):
        return list(self.edges.keys())

    def GetEdges(self):
        return self.edges

    def AddEdge(self, node1, node2):
        if node1 not in self.GetNodes():
            self.AddNode(node1)
        if node2 not in self.edges[node1]:
            self.edges[node1].append(node2)

    def RemoveEdge(self, node1, node2):
        if node1 not in self.edges or node2 not in self.edges[node1]:
            print("ERROR: can't remove edge", node1, "->", node2)
            print(self.edges)
            return
        self.edges[node1].remove(node2)

    def OutDegree(self, node):
        return len(self.edges[node])

    def InDegree(self, node):
        deg = 0
        for node2 in self.GetNodes():
            if node in self.GetNeighbors(node2):
                deg += 1
        return deg

    def GetNeighbors(self, node):
        return self.edges.get(node, [])
            
    def GetPath(self, source, target):
        # find path by BFS:
        predecessor = {node: -1 for node in self.GetNodes()}
        predecessor[source] = 0
        visited = {node: False for node in self.GetNodes()}
        queue = [source]
        while len(queue) > 0:
            current = queue.pop(0)
            visited[current] = True
            for neighbor in self.GetNeighbors(current):
                if not visited[neighbor] and neighbor not in queue:
                    queue.append(neighbor)
                    predecessor[neighbor] = current
                if neighbor == target:
                    queue = []
                    break
        # build path from predecessor info:
        if predecessor[target] == -1:
            return []
        path = [target]
        while path[0] != source:
            path = [predecessor[path[0]]] + path[:]
        return path

    def TopologicalSort(self):
        # determine topological sorting of graph by Kahn's algorithm;
        # edges are removed by this algorithm
        L = []
        S = [node for node in self.GetNodes() if self.InDegree(node) == 0]
        while len(S) > 0:
            n = S.pop(0)
            L.append(n)
            for m in self.GetNeighbors(n)[:]:
                self.RemoveEdge(n, m)
                if self.InDegree(m) == 0:
                    S.append(m)
        for node in self.GetNodes():
            if self.edges[node] != []:
                print("ERROR: graph has cycle!", self.edges)
                return
        return L


while True:
    n = int(input())
    if n == 0:
        break
    G = DirectedGraph()
    prices = {}
    for _ in range(n):
        item, price = input().split()
        prices[item] = int(price)
    m = int(input())
    recipes = {}
    for _ in range(m):
        inp = input().split()
        item = inp[0]
        recipes[item] = inp[2:]
        for source in inp[2:]:
            G.AddEdge(item, source)
    target = input().strip()
    for item in G.TopologicalSort()[::-1]:
        if item in recipes:
            prices[item] = min(prices[item], sum([prices[source] for source in recipes[item]]))
    print(prices[target])

Measured memory_bytes: 8024