#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const int INF = INT_MAX / 8;

class Edge{
public:
    int to, start, arrival, cost;
    Edge(){
    }
    Edge(int to0, int start0, int arrival0, int cost0){
        to = to0;
        start = start0;
        arrival = arrival0;
        cost = cost0;
    }
};

vector<vector<Edge> > edges;
vector<vector<Edge> > revEdges;

void solve1(int startPos, vector<vector<int> >& minCost)
{
    int n = edges.size();
    minCost.assign(n, vector<int>(601, INF));
    multimap<int, pair<int, int> > mm;
    minCost[startPos][0] = 0;
    mm.insert(make_pair(0, make_pair(startPos, 0)));

    while(!mm.empty()){
        int cost = mm.begin()->first;
        int pos = mm.begin()->second.first;
        int time = mm.begin()->second.second;
        mm.erase(mm.begin());
        if(cost > minCost[pos][time])
            continue;

        for(unsigned i=0; i<edges[pos].size(); ++i){
            if(time <= edges[pos][i].start){
                int pos2 = edges[pos][i].to;
                int cost2 = cost + edges[pos][i].cost;
                int time2 = edges[pos][i].arrival;
                if(cost2 < minCost[pos2][time2]){
                    minCost[pos2][time2] = cost2;
                    mm.insert(make_pair(cost2, make_pair(pos2, time2)));
                }
            }
        }
    }
}

void solve2(int goalPos, vector<vector<int> >& minCost)
{
    int n = revEdges.size();
    minCost.assign(n, vector<int>(601, INF));
    multimap<int, pair<int, int> > mm;
    minCost[goalPos][600] = 0;
    mm.insert(make_pair(0, make_pair(goalPos, 600)));

    while(!mm.empty()){
        int cost = mm.begin()->first;
        int pos = mm.begin()->second.first;
        int time = mm.begin()->second.second;
        mm.erase(mm.begin());
        if(cost > minCost[pos][time])
            continue;

        for(unsigned i=0; i<revEdges[pos].size(); ++i){
            if(time >= revEdges[pos][i].arrival){
                int pos2 = revEdges[pos][i].to;
                int cost2 = cost + revEdges[pos][i].cost;
                int time2 = revEdges[pos][i].start;
                if(cost2 < minCost[pos2][time2]){
                    minCost[pos2][time2] = cost2;
                    mm.insert(make_pair(cost2, make_pair(pos2, time2)));
                }
            }
        }
    }
}

int main()
{
    for(;;){
        int m;
        cin >> m;
        if(m == 0)
            return 0;

        map<string, int> index;
        index["Hakodate"] = 0;
        index["Tokyo"] = 1;
        int n = 2;
        edges.assign(n, vector<Edge>(0));
        revEdges.assign(n, vector<Edge>(0));
        for(int i=0; i<m; ++i){
            string s1, s2;
            int h1, m1, h2, m2, cost;
            char c;
            cin >> s1 >> h1 >> c >> m1 >> s2 >> h2 >> c >> m2 >> cost;
            int t1 = h1 * 60 + m1;
            int t2 = h2 * 60 + m2;
            if(t1 >= 8 * 60 && t2 <= 18 * 60){
                map<string, int>::iterator it;
                int j1, j2;
                it = index.find(s1);
                if(it == index.end()){
                    j1 = n;
                    index[s1] = j1;
                    ++ n;
                    edges.resize(n);
                    revEdges.resize(n);
                }else{
                    j1 = it->second;
                }
                it = index.find(s2);
                if(it == index.end()){
                    j2 = n;
                    index[s2] = j2;
                    ++ n;
                    edges.resize(n);
                    revEdges.resize(n);
                }else{
                    j2 = it->second;
                }
                t1 -= 8 * 60;
                t2 -= 8 * 60;
                edges[j1].push_back(Edge(j2, t1, t2, cost));
                revEdges[j2].push_back(Edge(j1, t1, t2, cost));
            }
        }

        vector<vector<vector<int> > > minCost(4);
        solve1(0, minCost[0]);
        solve1(1, minCost[1]);
        solve2(0, minCost[2]);
        solve2(1, minCost[3]);
        int ret = INF;
        for(int i=0; i<n; ++i){
            for(int j=0; j<600; ++j){
                minCost[0][i][j+1] = min(minCost[0][i][j+1], minCost[0][i][j]);
                minCost[1][i][j+1] = min(minCost[1][i][j+1], minCost[1][i][j]);
            }
            for(int j=600; j>0; --j){
                minCost[2][i][j-1] = min(minCost[2][i][j-1], minCost[2][i][j]);
                minCost[3][i][j-1] = min(minCost[3][i][j-1], minCost[3][i][j]);
            }
            for(int j=0; j<=570; ++j)
                ret = min(ret, minCost[0][i][j] + minCost[1][i][j] + minCost[2][i][j+30] + minCost[3][i][j+30]);
        }

        if(ret < INF)
            cout << ret << endl;
        else
            cout << 0 << endl;
    }
}

Measured memory_bytes: 0