#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<algorithm>
#include<map>
#include<cstring>
#include<set>
using namespace std;
const int maxn = 1001;
const int inf = 1000000001;
int n, m, k, ds, st;
int weight[maxn];
int d[maxn], num[maxn], w[maxn], Count[maxn], pre[maxn];
int G[maxn][maxn];
bool vis[maxn];
map<string, int>cityToindex;
map<int, string>indexTocity;
void dj(int s)
{
fill(d, d + maxn, inf);
memset(w, 0, sizeof(w));
memset(num, 0, sizeof(num));
memset(Count, 0, sizeof(Count));
d[s] = 0;
num[s] = 1;
for (int i = 0; i < n; i++)
{
int u = -1, min = inf;
for (int j = 0; j < n; j++)
{
if (vis[j] == false && d[j] < min)
{
u = j;
min = d[j];
}
}
if (u == -1)
return;
vis[u] = true;
for (int v = 0; v < n; v++)
{
if (vis[v] == false)
{
if (d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
w[v] = w[u] + weight[v];
num[v] = num[u];
Count[v] = Count[u] + 1;
pre[v] = u;
}
else if (d[u] + G[u][v] == d[v])
{
num[v] += num[u];
if (w[u] + weight[v] > w[v])
{
w[v] = w[u] + weight[v];
Count[v] = Count[u] + 1;
pre[v] = u;
}
else if (w[u] + weight[v] == w[v])
{
double uAvg = 1.0 * (w[u] + weight[v]) / (Count[u] + 1);
double vAvg = 1.0 * w[v] / Count[v];
if (uAvg > vAvg)
{
Count[v] = Count[u] + 1;
pre[v] = u;
}
}
}
}
}
}
}
void print(int v)
{
if (v == 0)
{
cout << indexTocity[v];
return;
}
print(pre[v]);
cout << "->" << indexTocity[v];
}
int main()
{
string start, city1, city2;
cin >> n >> m >> start;
cityToindex[start] = 0;
indexTocity[0] = start;
for (int i = 1; i < n; i++)
{
cin >> city1 >> weight[i];
cityToindex[city1] = i;
indexTocity[i] = city1;
}
fill(G[0], G[0] + maxn * maxn, inf);
for (int i = 0; i < m; i++)
{
cin >> city1 >> city2;
int c1 = cityToindex[city1], c2 = cityToindex[city2];
cin >> G[c1][c2];
G[c2][c1] = G[c1][c2];
}
dj(0);
int rom = cityToindex["ROM"];
cout << num[rom] << " " << d[rom] << " " << w[rom] << " " << w[rom] / Count[rom] << endl;
print(rom);
}