#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f
const int N=200+5;
int n,m,p;
int a[N],pre[N];
string st,ed;
map<string,int>mp;
map<int,string>mp2;
struct edge{
int to,w;
};
struct node{
int id,dis;
bool operator<(const node& a)const{
return dis>a.dis;
}
};
vector<edge>e[N];
void print(int s,int u){
if(s==u){
cout<<mp2[s];
return;
}
print(s,pre[u]);
cout<<"->"<<mp2[u];
}
int dis[N],done[N],cnt[N],path[N],num[N];
void dijkstra(){
int s=0;
priority_queue<node>q;
q.push({s,0});
for(int i=0;i<n;i++){
dis[i]=inf;
}
dis[0]=0;
path[0]=1;
while(q.size()){
auto u=q.top();
q.pop();
if(done[u.id]) continue;
done[u.id]=1;
for(auto it:e[u.id]){
auto x=it;
if(done[x.to]) continue;
if(dis[x.to]>u.dis+x.w){
dis[x.to]=u.dis+x.w;
path[x.to]=path[u.id];
cnt[x.to]=cnt[u.id]+1;
num[x.to]=num[u.id]+a[x.to];
q.push({x.to,dis[x.to]});
pre[x.to]=u.id;
}
else if(dis[x.to]==u.dis+x.w){
path[x.to]+=path[u.id];
if(cnt[u.id]+1>cnt[x.to]){
cnt[x.to]=cnt[u.id]+1;
num[x.to]=num[u.id]+a[x.to];
pre[x.to]=u.id;
}
else if(cnt[u.id]+1==cnt[x.to]&&num[u.id]+a[x.to]>num[x.to]){
num[x.to]=num[u.id]+a[x.to];
pre[x.to]=u.id;
}
}
}
}
print(s,p);
cout<<endl<<path[p]<<" "<<dis[p]<<" "<<num[p];
}
void solve(){
cin>>n>>m>>st>>ed;
mp[st]=0;
mp2[0]=st;
for(int i=1;i<n;i++){
string s;
cin>>s>>a[i];
mp[s]=i;
mp2[i]=s;
if(s==ed) p=i;
}
for(int i=1;i<=m;i++){
string s1,s2;
int x;
cin>>s1>>s2>>x;
e[mp[s1]].push_back({mp[s2],x});
e[mp[s2]].push_back({mp[s1],x});
}
dijkstra();
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--) solve();
return 0;
}