Problem: Kotoko, a housewife, was enthusiastic about keeping food costs down during this recession. Be sure to check the newspaper advertisement every morning. Make a good list of what to buy and the cheapest-selling shops, and go shopping by riding a bicycle in a combat style called apron sandals while walking through the shops.

So, as a husband, you decided to create a housekeeping book program with your favorite programming in order to help Kotoko even a little. The program inputs the name and price (yen) of the items sold to each supermarket, the items that Kotoko needs, and outputs the minimum amount to collect all the items.

Kotoko has to leave the house, collect the necessary items, and return home. Therefore, you who care about Kotoko decided to add a function to report the distance of the route with the shorter distance, considering that there are multiple shopping routes with the same minimum amount. Therefore, the program also inputs information on the road connecting the supermarket and the house.

Let the number of supers be n, and each super is assigned a number from 1 to n. Furthermore, Kotoko's house is number 0. Road information is given by these number pairs and their distances (integers).



Input

Multiple datasets are given as input. The format of each dataset is as follows:

n (number of supermarkets: integer)
k1 name1 value1 name2 value2 ... namek1 valuek1 (number of item types in the first supermarket, first item name and price, second item name and price ,,,: integer and string blanks Separation)
k2 name1 value1 name2 value2 ... namek2 valuek2 (number of item types in the second supermarket, first item name and price, second item name and price ,,,: integer and string blanks Separation)
..
..
kn name1 value1 name2 value2 ... namekn valuekn (number of item types in the nth supermarket, first item name and price, second item name and price ,,,: integer and string blanks Separation)
q (Number of items required: Integer)
name1 (Name of the first required item: string)
name2 (name of the second required item: string)
..
..
nameq (name of the qth required item: string)
m (number of roads: integer)
s1 t1 d1 (Information on the first road: Blank-separated integers)
s2 t2 d2 (Second road information: space-separated integer)
..
..
sm tm dm (mth road information: blank-separated integer)


si ti di indicates that the sith supermarket (or house) and the tith supermarket (or house) can move back and forth in both directions, and the distance is di.

You will be given a way to get to all the supermarkets from your house (via the supermarket).

n is less than or equal to 10 and q is less than or equal to 15. ki is 100 or less, the string of the item name does not exceed 20 characters, and the price of the item does not exceed 10000. Also, the length of the road does not exceed 1000.

When n is 0, it is the end of input.

Output

For each dataset, separate the minimum amount and distance with a single space and output on one line. However, if you cannot collect all the necessary items, output "impossible".

Example

Input

3
3 apple 100 banana 200 egg 300
3 apple 150 banana 100 cola 200
3 apple 100 banana 150 cola 200
3
apple
banana
cola
5
0 2 4
0 1 3
0 3 3
1 2 3
2 3 5
3
3 apple 100 banana 200 egg 300
3 apple 150 banana 100 cola 200
3 apple 100 banana 150 cola 200
4
apple
banana
cola
jump
5
0 2 4
0 1 3
0 3 3
1 2 3
2 3 5
0


Output

400 10
impossible

Solution (in CPP):

Solution:
#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


int N,num_need,E;
int POW[17];
int num_item[10];
int first_value[10][100],value[10][15];
int min_dist[11][11];
int TSP[1024][10];
char name[10][100][21],need[15][21];


bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void func(){

	//各スーパーの販売品情報を取得
	for(int i = 0; i < N; i++){
		scanf("%d",&num_item[i]);
		for(int k = 0; k < num_item[i]; k++){
			scanf("%s %d",name[i][k],&first_value[i][k]);
		}
	}

	scanf("%d",&num_need);

	for(int i = 0; i < num_need; i++){
		scanf("%s",need[i]);
	}

	//各店の販売品情報を、必要な商品情報で更新する
	for(int i = 0; i < N; i++){
		for(int k = 0; k < num_need; k++){
			value[i][k] = -1; //-1:該当商品なし
		}
	}

	for(int i = 0; i < num_need; i++){ //必要な商品のループ
		for(int k = 0; k < N; k++){ //店のループ
			for(int p = 0; p < num_item[k]; p++){ //店の商品のループ
				if(!strCmp(name[k][p],need[i]))continue;

				value[k][i] = first_value[k][p]; //i番目の商品の値段を記録

				break;
			}
		}
	}

	for(int i = 0; i <= N; i++){
		for(int k = 0; k <= N; k++){
			if(i != k){
				min_dist[i][k] = BIG_NUM;
			}else{
				min_dist[i][k] = 0;
			}
		}
	}

	scanf("%d",&E);

	//★グラフでは、各店を1オリジンで扱う★
	int from,to,dist;
	for(int loop = 0; loop < E; loop++){
		scanf("%d %d %d",&from,&to,&dist);
		min_dist[from][to] = dist;
		min_dist[to][from] = dist;
	}

	//ワーシャルフロイド
	for(int mid = 0; mid <= N; mid++){
		for(int start = 0; start <= N; start++){
			if(min_dist[start][mid] == BIG_NUM)continue;
			for(int goal = 0; goal <= N; goal++){
				if(min_dist[mid][goal] == BIG_NUM)continue;

				min_dist[start][goal] = min(min_dist[start][goal],min_dist[start][mid]+min_dist[mid][goal]);
			}
		}
	}

	int ans_dist = BIG_NUM,ans_cost = BIG_NUM,tmp_dist,tmp_cost;
	int my_house = 0,next_state,next_cost;

	bool is_visit_store[N];
	int min_item[num_need];

	for(int state = 1; state < POW[N]; state++){ //訪れる店の集合のループ
		//今回のTSPで訪れる店を計算する
		for(int loop = 0; loop < N; loop++){
			if(state & (1 << loop)){
				is_visit_store[loop] = true;
			}else{
				is_visit_store[loop] = false;
			}
		}
		for(int i = 0; i < num_need; i++)min_item[i] = BIG_NUM;

		//最小価格を求めつつ、今回訪れる店の組合せで欲しい商品が揃うか調べる
		for(int i = 0; i < num_need; i++){
			for(int k = 0; k < N; k++){
				if(!is_visit_store[k])continue;

				if(value[k][i] != -1){
					min_item[i] = min(min_item[i],value[k][i]);
				}
			}
		}

		tmp_cost = 0;
		for(int i = 0; i < num_need; i++){
			if(min_item[i] == BIG_NUM){
				tmp_cost = BIG_NUM;
				break;
			}
			tmp_cost += min_item[i];
		}

		if(tmp_cost == BIG_NUM || tmp_cost > ans_cost)continue;

		for(int i = 0; i <= state; i++){
			for(int k = 0; k < N; k++)TSP[i][k] = BIG_NUM;
		}

		for(int first_store = 0; first_store < N; first_store++){
			if(!is_visit_store[first_store])continue;
			TSP[POW[first_store]][first_store] = min_dist[my_house][first_store+1];
		}

		for(int tmp_state = 1; tmp_state < state; tmp_state++){
			for(int last_store = 0; last_store < N; last_store++){
				if(TSP[tmp_state][last_store] == BIG_NUM)continue;

				//次の店へ
				for(int next_store = 0; next_store < N; next_store++){
					if(!is_visit_store[next_store])continue;
					if(tmp_state & (1 << next_store))continue; //訪問済ならSKIP

					next_state = tmp_state+POW[next_store];
					next_cost = TSP[tmp_state][last_store]+min_dist[last_store+1][next_store+1]; //★グラフは1オリジン
					TSP[next_state][next_store] = min(TSP[next_state][next_store],next_cost);
				}
			}
		}

		tmp_dist = BIG_NUM;
		for(int last_store = 0; last_store < N; last_store++){
			if(!is_visit_store[last_store])continue;

			tmp_dist = min(tmp_dist,TSP[state][last_store]+min_dist[my_house][last_store+1]);
		}

		if(ans_cost == tmp_cost){

			ans_dist = min(ans_dist,tmp_dist);

		}else if(ans_cost > tmp_cost){
			ans_cost = tmp_cost;
			ans_dist = tmp_dist;
		}
	}

	if(ans_dist == BIG_NUM){
		printf("impossible\n");
	}else{
		printf("%d %d\n",ans_cost,ans_dist);
	}
}



int main(){

	for(int i = 0; i < 17; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}