# include <iostream>
# include <cstdio>
# include <queue>
# include <map>
# include <vector>
# include <algorithm>
# include <cstdlib>
# include <limits>
# include <utility>
# include <cstring>
# include <unistd.h>
# include <ctime>
using namespace std;

typedef unsigned long long ullong;
typedef long long llong;
class FastIO
{
private:
    const static int READLIMIT  = 1048576;
	const static int WRITELIMIT = 524288;
	int ReadIndex, WriteIndex, BufferLength;
	unsigned char ReadBuffer  [READLIMIT];
	unsigned char WriteBuffer [WRITELIMIT];
	unsigned char TempNumber  [25];
	bool bIsLittleEndian;
	void Fetch()
	{
		if (ReadIndex >= BufferLength)
		{
			ReadIndex = 0;
			BufferLength = fread (ReadBuffer,  1, READLIMIT, stdin);
		}
	}
public:
	FastIO (const char * in = "", const char * out = "")
	{
		if (in  != "") freopen (in,  "r", stdin);
		if (out != "") freopen (out, "w", stdout);
		ReadIndex = 0; WriteIndex = 0; BufferLength = 0;
		union
		{
			uint32_t i;
			char c[4];
		} bint = {0x01020304};
		bIsLittleEndian = (bint.c[0] == 1);
	}
	void SetStreams (const char * in = "", const char * out = "")
	{
		if (in  != "") 
		{
			freopen (in,  "r", stdin);
			ReadIndex = BufferLength = 0;
		}
		if (out != "")
		{
			freopen (out, "w", stdout);
			WriteIndex = 0;
		}
	}
	bool IsEOF()
	{
		Fetch();
		return (BufferLength == 0);
	}
	void Flush(bool ForceFlush = false)
	{
		if ((WriteIndex >= WRITELIMIT) || ForceFlush)
		{
			fwrite (WriteBuffer, 1, WriteIndex, stdout);
			WriteIndex = 0;
		}
	}
	void getCString(char * String, int MaxLength, bool bIsSpaceBreaks = true)
	{
		bool isDone = false, isFirstDigit = true; int CurrentIndex = 0; unsigned char CurrentChar;
		while (!isDone || CurrentIndex == MaxLength)
		{
			if (ReadIndex >= BufferLength) Fetch();
			if (BufferLength == 0)
				isDone = true;
			else
			{
				CurrentChar = ReadBuffer [ReadIndex++];
				if (isFirstDigit)
				{
					if (CurrentChar == 10 || CurrentChar == '\t') continue;
					isFirstDigit = false;
				}
				if (CurrentChar == 10 || CurrentChar == 13 || (bIsSpaceBreaks && CurrentChar == ' ')) isDone = true;
				else String [CurrentIndex++] = CurrentChar;
			}
		}
		String [CurrentIndex] = 0;
	}
	ullong getNumber()
	{
		ullong Number = 0;
		bool isDone = false, isFirstDigit = true;
		while (!isDone)
		{
			if (ReadIndex >= BufferLength) Fetch();
			if (BufferLength == 0)
				isDone = true;
			else
			{
				int CurrentChar = ReadBuffer [ReadIndex++];
				if (isFirstDigit)
				{
					if (CurrentChar > 57 || CurrentChar < 48) continue;
					isFirstDigit = false;
				}
				if (CurrentChar > 57 || CurrentChar < 48) isDone = true;
				else Number = ((Number << 3) + (Number << 1)) + (CurrentChar - '0');
			}
		}
		return Number;
	}
	llong getSignedNumber()
	{
		llong Number = 0;
		bool isDone = false, isNegative = false, isFirstChar = true;
		while (!isDone)
		{
			if (ReadIndex >= BufferLength) Fetch();
			if (BufferLength == 0)
				isDone = true;
			else
			{
				int CurrentChar = ReadBuffer [ReadIndex++];
				if (isFirstChar)
				{
					if ((CurrentChar > 57 || CurrentChar < 48) && CurrentChar != '-') continue;
					isNegative = (CurrentChar == '-');
					isFirstChar = !isFirstChar;
					if (CurrentChar == '-') continue;
				}
				if (CurrentChar > 57 || CurrentChar < 48) isDone = true;
				else Number = ((Number << 3) + (Number << 1)) + (CurrentChar - '0');
			}
		}
		return (isNegative && Number?-Number:Number);
	}
	void WriteNumber (ullong Number, bool NewLineNeeded = true)
	{
		int idx = 0, temp;
		if (!Number) TempNumber [idx++] = '0';
		while (Number)
		{
			temp = Number % 10;
			Number /= 10;
			TempNumber [idx++] = temp + '0';
		}
		TempNumber [idx--] = '\0';
		for (int i = idx; i > (idx - i); i--)
		{
			temp = TempNumber [i];
			TempNumber [i] = TempNumber[idx - i];
			TempNumber[idx - i] = temp;
		}
		idx++;
		for (int i = 0; i < idx; i++)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = TempNumber [i];
		}
		if (NewLineNeeded)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = '\n';
		}
	}
	void WriteSignedNumber (llong Number, bool NewLineNeeded = true)
	{
		int idx = 0, temp; bool isNegative = false;
		if (Number < 0)
		{
			isNegative = true;
			Number = -Number;
		}
		if (!Number) TempNumber [idx++] = '0';
		while (Number)
		{
			temp = Number % 10;
			Number /= 10;
			TempNumber [idx++] = temp + '0';
		}
		TempNumber [idx--] = '\0';
		for (int i = idx; i > (idx - i); i--)
		{
			temp = TempNumber [i];
			TempNumber [i] = TempNumber[idx - i];
			TempNumber[idx - i] = temp;
		}
		idx++;
		if (isNegative)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = '-';
		}
		for (int i = 0; i < idx; i++)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = TempNumber [i];
		}
		if (NewLineNeeded)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = '\n';
		}
	}
	void WriteCString (const char * String, int MaxLength = 0, bool NewLineNeeded = true)
	{
		if (MaxLength == 0) MaxLength = strlen (String);
		for (int i = 0; i < MaxLength; i++)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = String [i];
		}
		if (NewLineNeeded)
		{
			if (WriteIndex >= WRITELIMIT && WriteIndex) Flush();
			WriteBuffer [WriteIndex++] = '\n';
		}
	}
};

const ullong MAXIMUM = numeric_limits <ullong>::max();
vector <pair <int, ullong> > Weights [10001];
pair <char [12], int> CityMap [10001];
ullong Distances [10001];
struct FindGreaterObject
{
	bool operator () (pair <int, ullong > & A, pair <int, ullong > & B) const
	{
		return A.second > B.second;
	}
};
priority_queue <pair <int, ullong>, vector <pair <int, ullong> >, FindGreaterObject > Q;
int ComparePairs (const void * first, const void * second)
{
	return strcmp (((pair <char [12], int> *)first)->first, ((pair <char [12], int> *)second)->first);
}
int main(int argc, char const *argv[])
{
	FastIO io;
	int T, TVertices, TNeighbours, TDistances, NeightbourIndex, Distance, Start = 0, End = 0; char City[12], City1[12];
	pair <int, ullong> Current;
	T = io.getNumber();
	while (T--)
	{
		TVertices = io.getNumber();
		for (int i = 1; i <= TVertices; i++)
		{
			io.getCString (CityMap [i-1].first, 11);
			CityMap [i-1].second = i;
			TNeighbours = io.getNumber();
			for (int j = 0; j < TNeighbours; j++)
			{
				NeightbourIndex = io.getNumber(); Distance = io.getNumber();
				Weights [i].push_back (make_pair (NeightbourIndex, Distance));
			}
		}
		qsort (CityMap, TVertices, sizeof (pair <char [12], int>), ComparePairs);
		TDistances = io.getNumber();
		for (int i = 0; i < TDistances; i++)
		{
			Start = End = -1;
			io.getCString (City, 11); io.getCString (City1, 11);
			pair <char [12], int> * CityIndex = (pair <char [12], int> *)bsearch (City, CityMap, TVertices, sizeof (pair <char [12], int>), ComparePairs);
			Start = CityIndex->second;
			CityIndex = (pair <char [12], int> *) bsearch (City1, CityMap, TVertices, sizeof (pair <char [12], int>), ComparePairs);
			End   = CityIndex->second;
			fill (Distances, Distances + TVertices + 1, MAXIMUM);
			Distances [Start] = 0;
			while (!Q.empty()) Q.pop();
			Q.push (make_pair (Start, 0));
			while (!Q.empty())
			{
				Current = Q.top(); Q.pop();
				if (Distances [Current.first] < Current.second) continue;
				if (Current.first == End) break;
				for (vector <pair <int, ullong> >::iterator it = Weights[Current.first].begin(); it != Weights[Current.first].end(); it++)
				{
					ullong AlternateDistance = Distances [Current.first] + (*it).second;
					if (Distances [(*it).first] > AlternateDistance)
					{
						Distances [(*it).first] = AlternateDistance;
						Q.push (make_pair ((*it).first, AlternateDistance));
					}
				}
			}
			io.WriteNumber(Distances [End]);
		}
	}
	io.Flush(true);
	return 0;
}