#define _CRT_SECURE_NO_WARNINGS #define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING #include using namespace std; unordered_map m; int getId(const char *str) { auto ite = m.find(str); if (ite != m.end()) return ite->second; else return m[str] = m.size(); } const int N = 20050; int adj[N], nxt[N], to[N], len[N], dis[N], ecnt; inline void addEdge(int f, int t, int l) { ecnt++; nxt[ecnt] = adj[f]; adj[f] = ecnt; to[ecnt] = t; len[ecnt] = l; } inline void rst() { m.clear(); ecnt = 0; memset(adj, 0, sizeof(adj)); memset(dis, 0x3f3f3f3f, sizeof(dis)); } char buf1[50], buf2[50]; struct node { int u, w; }; bool operator<(const node x, const node y) noexcept { return x.w > y.w; } priority_queue h; int main() { int n; while (scanf("%d", &n), ~n) { rst(); scanf("%s%s", buf1, buf2); int S = getId(buf1), T = getId(buf2); for (int i = 0, x, y, z; i < n; i++) { scanf("%s%s%d", buf1, buf2, &z); x = getId(buf1), y = getId(buf2); addEdge(x, y, z), addEdge(y, x, z); } dis[S] = 0; h.push({S, dis[S]}); while (!h.empty()) { auto u = h.top().u, w = h.top().w; h.pop(); if (w != dis[u]) continue; for (int e = adj[u]; e; e = nxt[e]) if (dis[to[e]] > w + len[e]) dis[to[e]] = w + len[e], h.push({to[e], dis[to[e]]}); } if (dis[T] > 15000) dis[T] = -1; printf("%d\n", dis[T]); } return 0; }