# 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;
}