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


#define NUM 100
#define BASE 480
#define MAX 600

enum Type{
	A,
	B,
};

struct Edge{
	Edge(int arg_to,int arg_cost,int arg_to_time){
		to = arg_to;
		cost = arg_cost;
		to_time = arg_to_time;
	}
	int to,cost,to_time;
};

int N;
int node_index;
int min_cost[2][NUM][601],return_min_cost[2][NUM][601];
int A_id = 0,B_id = 1;
const string start_A = "Hakodate";
const string start_B = "Tokyo";

map<string,int> MAP;
map<int,int> CALC;
vector<Edge> G[NUM][601],rev_G[NUM][601];

//時刻を分に直す
int getNUM(char work[6]){

	int hour = 10*(work[0]-'0')+(work[1]-'0');
	int minute = 10*(work[3]-'0')+(work[4]-'0');

	return 60*hour+minute;
}

//8時～18時の時間帯か
bool rangeCheck(int tmp_time){
	if(tmp_time >= BASE && tmp_time <= BASE+MAX)return true;
	else{
		return false;
	}
}

void func(){

	MAP.clear();
	for(int i = 0; i < NUM; i++){
		for(int k = 0; k <= MAX; k++){
			G[i][k].clear();
			rev_G[i][k].clear();
		}
	}

	string start,arrival;
	char start_buf[6],arrive_buf[6];
	int start_time,arrive_time;
	int price,start_id,arrive_id;

	MAP[start_A] = A_id;
	MAP[start_B] = B_id;

	node_index = 2;

	for(int loop = 0; loop < N; loop++){
		cin >> start >> start_buf >> arrival >> arrive_buf >> price;

		auto at = MAP.find(start);

		if(at == MAP.end()){
			MAP[start] = node_index;
			start_id = node_index;
			node_index++;

		}else{
			start_id = MAP[start];
		}

		at = MAP.find(arrival);

		if(at == MAP.end()){
			MAP[arrival] = node_index;
			arrive_id = node_index;
			node_index++;

		}else{
			arrive_id = MAP[arrival];
		}

		start_time = getNUM(start_buf);
		arrive_time = getNUM(arrive_buf);

		if(rangeCheck(start_time) == false || rangeCheck(arrive_time) == false)continue;

		start_time -= BASE;
		arrive_time -= BASE;

		G[start_id][start_time].push_back(Edge(arrive_id,price,arrive_time));
		rev_G[arrive_id][arrive_time].push_back(Edge(start_id,price,start_time));
	}

	for(int i = 0; i < 2; i++){
		for(int town = 0; town < node_index; town++){
			for(int time = 0; time <= MAX; time++){
				min_cost[i][town][time] = BIG_NUM;
				return_min_cost[i][town][time] = BIG_NUM;
			}
		}
	}

	min_cost[A][0][0] = 0;
	min_cost[B][1][0] = 0;

	for(int i = 0; i < 2; i++){
		for(int time = 0; time < MAX; time++){
			for(int town = 0; town < node_index; town++){
				min_cost[i][town][time+1] = min(min_cost[i][town][time+1],min_cost[i][town][time]);
				for(int a = 0; a < G[town][time].size(); a++){
					min_cost[i][G[town][time][a].to][G[town][time][a].to_time] = min(min_cost[i][G[town][time][a].to][G[town][time][a].to_time],
							min_cost[i][town][time]+G[town][time][a].cost);
				}
			}
		}
	}

	return_min_cost[A][0][MAX] = 0;
	return_min_cost[B][1][MAX] = 0;

	for(int i = 0; i < 2; i++) {
		for(int time = MAX; time > 0; time--) {
			for(int town = 0; town < node_index; town++) {
				return_min_cost[i][town][time-1] = min(return_min_cost[i][town][time-1],return_min_cost[i][town][time]);
				for(int a = 0; a < rev_G[town][time].size(); a++) {
					return_min_cost[i][rev_G[town][time][a].to][rev_G[town][time][a].to_time] =
							min(return_min_cost[i][rev_G[town][time][a].to][rev_G[town][time][a].to_time],
												return_min_cost[i][town][time]+rev_G[town][time][a].cost);
				}
			}
		}
	}

	int ans = BIG_NUM;
	for(int time = 0; time+30 <= MAX; time++) {
		for(int town = 0; town < node_index; town++) {
			if(min_cost[A][town][time] == BIG_NUM || min_cost[B][town][time] == BIG_NUM ||
					return_min_cost[A][town][time+30] == BIG_NUM || return_min_cost[B][town][time+30] == BIG_NUM)continue;
			ans = min(ans, min_cost[A][town][time]+min_cost[B][town][time]+return_min_cost[A][town][time+30]+return_min_cost[B][town][time+30]);
		}
	}

	if(ans == BIG_NUM){
		printf("0\n");
	}else{
		printf("%d\n",ans);
	}
}

int main(){

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

		func();
	}
	return 0;
}



Measured memory_bytes: 6396