#include<map>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int INF=((1<<31)-1)/4;

struct train{ int u,v,t1,t2,cost; };
bool cmp0(const train &T1,const train &T2){ return T1.t1<T2.t1 || T1.t1==T2.t1 && T1.t2<T2.t2; } // (t1,t2) の昇順
bool cmp1(const train &T1,const train &T2){ return T1.t2>T2.t2 || T1.t2==T2.t2 && T1.t1>T2.t1; } // (t2,t1) の降順

int decode(const char *t){
	int hh=(t[0]-'0')*10+(t[1]-'0');
	int mm=(t[3]-'0')*10+(t[4]-'0');
	return 60*hh+mm-8*60;
}

void calc_time(int n,int m,train *T,int dp[2][601][2001],int s){
	rep(i,2) rep(t,601) rep(u,n) dp[i][t][u]=INF;

	sort(T,T+m,cmp0);
	dp[0][0][s]=0;
	int iter=0;
	rep(t,601){
		if(t<600){ // 動かずに一分過ごす
			rep(u,n) dp[0][t+1][u]=min(dp[0][t+1][u],dp[0][t][u]);
		}
		while(iter<m && T[iter].t1==t){ // 電車に乗る
			dp[0][T[iter].t2][T[iter].v]=min(dp[0][T[iter].t2][T[iter].v],dp[0][t][T[iter].u]+T[iter].cost);
			iter++;
		}
	}

	sort(T,T+m,cmp1);
	dp[1][600][s]=0;
	iter=0;
	for(int t=600;t>=0;t--){
		if(t>0){
			rep(u,n) dp[1][t-1][u]=min(dp[1][t-1][u],dp[1][t][u]);
		}
		while(iter<m && T[iter].t2==t){
			dp[1][T[iter].t1][T[iter].u]=min(dp[1][T[iter].t1][T[iter].u],dp[1][t][T[iter].v]+T[iter].cost);
			iter++;
		}
	}
}

int main(){
	for(int m;scanf("%d",&m),m;){
		int n=0;
		map<string,int> f;
		f["Hakodate"]=n++;
		f["Tokyo"]=n++;

		train T[2000];
		rep(i,m){
			char s1[32],t1[8],s2[32],t2[8];
			int cost; scanf("%s%s%s%s%d",s1,t1,s2,t2,&cost);
			if(f.count(s1)==0) f[s1]=n++;
			if(f.count(s2)==0) f[s2]=n++;
			int tt1=decode(t1),tt2=decode(t2);
			if(0<=tt1 && tt2<=600){
				T[i]=(train){f[s1],f[s2],tt1,tt2,cost};
			}
			else{
				i--;
				m--;
			}
		}

		// 頂点が多すぎて MLE するので, 函館と東京の両方からたどり着ける頂点だけに制限する
		vector<int> G[4000];
		rep(i,m) G[T[i].u].push_back(T[i].v);
		bool vis[2][4000]={};
		rep(i,2){
			vis[i][i]=true;
			int Q[4000],head=0,tail=0;
			Q[tail++]=i;
			while(head<tail){
				int u=Q[head++];
				rep(j,G[u].size()){
					int v=G[u][j];
					if(!vis[i][v]) vis[i][v]=true, Q[tail++]=v;
				}
			}
		}
		bool kill[4000]={};
		vector<int> V;
		rep(u,n){
			if(!vis[0][u] || !vis[1][u]) kill[u]=true;
			else                         V.push_back(u);
		}
		rep(i,m){
			if(kill[T[i].u] || kill[T[i].v]){
				swap(T[i],T[m-1]);
				i--;
				m--;
			}
			else{
				T[i].u=lower_bound(V.begin(),V.end(),T[i].u)-V.begin();
				T[i].v=lower_bound(V.begin(),V.end(),T[i].v)-V.begin();
			}
		}

		// dp1[0][t][u] := ( 8:00 に函館にいて, 時刻 t に駅 u にいるときの最小コスト )
		// dp1[1][t][u] := ( 18:00 に函館に戻れて, 時刻 t に駅 u にいるときの最小コスト )
		// dp2 は dp1 の函館を東京に変えただけ.
		static int dp1[2][601][2001],dp2[2][601][2001];
		calc_time(n,m,T,dp1,0);
		calc_time(n,m,T,dp2,1);

		int ans=INF;
		rep(u,n) rep(t,600-30+1) {
			ans=min(ans,dp1[0][t][u]+dp1[1][t+30][u]+dp2[0][t][u]+dp2[1][t+30][u]);
		}
		printf("%d\n",ans<INF?ans:0);
	}

	return 0;
}