/*
Name: 利用kruskal的过程+hash+二分
Copyright: (处理字符串我写复杂了!)
Author: Try86
Date: 18/04/12 20:26
Description: 求连接两点的路径上的最小边权的最大值
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int L = 35;
const int S = 331;//hash表大小
const int N = 205;
const int M = 20000;
int sumVs, start, end, p[N];
char names[2][M][L], str[N][L], name1[L], name2[L];
struct edge {
int u;
int v;
int w;
}e[M];
struct node {//hash表数据结构相关信息
char str[L];
node *next;
node(char *ch, node *p) {
strcpy(str, ch);
next = p;
}
};
struct hash {
node *link;
}hashTable[S];
int cmp(const void *a, const void *b) {
return strcmp((char *)a, (char *)b);
}
void init() {
for (int i=0; i<S; ++i) hashTable[i].link = NULL;
return ;
}
unsigned int BKDRHash(char *str) {
unsigned int seed = 131;
unsigned int hash = 0;
while (*str) hash = hash * seed + (*str++);
return hash & 0x7FFFFFFF;
}
void insertAndFind(char *strName) {//字符串判重
int k = BKDRHash(strName) % S;
node *p = hashTable[k].link;
while (p) {
if (!strcmp(p->str, strName)) return ;
p = p->next;
}
node *q = new node(strName, hashTable[k].link);
hashTable[k].link = q;
strcpy(str[sumVs++], strName);
return ;
}
/*
void del(node *p) {
if (!p) return ;
del(p->next);
delete p;
return ;
}*/
int binarySearch(char *name, int n) {//二分查找字符串所在位置
int left = 0;
int right = n;
while (left <= right) {
int mid = (left + right) / 2;
if (!strcmp(str[mid], name)) return mid;
if (strcmp(str[mid], name) > 0) right = mid - 1;
else left = mid + 1;
}
}
void initS(int n) {
for (int i=1; i<=n; ++i) p[i] = i;
return ;
}
int find(int v) {
if (p[v] != v) p[v] = find(p[v]);
return p[v];
}
void join(edge e) {
int x = find(e.u);
int y = find(e.v);
if (x != y) p[x] = y;
return ;
}
int cmp1(const void *a, const void *b) {
return ((edge *)b)->w - ((edge *)a)->w;
}
int kruskal(int n, int m) {
initS(n);
qsort(e, m, sizeof(edge), cmp1);
for (int i=0; i<m; ++i) {
join(e[i]);
if (find(start) == find(end)) {//起点跟终点在同一个集合时,加入集合的最后一条边权既是所求的答案
return e[i].w;
}
}
}
int main() {
int n, m, t = 0;
while (scanf("%d%d", &n, &m), n+m) {
init();
sumVs = 0;
for (int i=0; i<m; ++i) {//输入数据,并判重
scanf ("%s%s%d", names[0][i], names[1][i], &e[i].w);
insertAndFind(names[0][i]);
insertAndFind(names[1][i]);
}
scanf ("%s%s", name1, name2);
qsort(str, sumVs, sizeof(str[0]), cmp);
for (int i=0; i<m; ++i) {//建图
int u = binarySearch(names[0][i], n) + 1;
int v = binarySearch(names[1][i], n) + 1;
e[i].u = u, e[i].v = v;
}
start = binarySearch(name1, n) + 1;//起点位置
end = binarySearch(name2, n) + 1;//终点位置
int ans = kruskal(n, m);
printf ("Scenario #%d\n%d tons\n\n", ++t, ans);
// for (int i=0; i<S; ++i) del(hashTable[i].link);
for (int i=0; i<S; ++i) {
node *p = hashTable[i].link;
while (p) {
hashTable[i].link = p->next;
delete p;
p = hashTable[i].link;
}
}
}
return 0;
}