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



Measured memory_bytes: 3308