#include <cassert>// c
#include <ctime>
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>
#include <tuple>

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(),(c).end()
#define FOR(i,l,r) for(int i=(int)l;i<(int)r;++i)
#define REP(i,n) FOR(i,0,n)
#define FORr(i,l,r) for(int i=(int)r-1;i>=(int)l;--i)
#define REPr(i,n) FORr(i,0,n)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end())
//debug
#define DUMP(x)  cerr << #x << " = " << (x)
#define LINE()    cerr<< " (L" << __LINE__ << ")"

template<typename T,typename U> T pmod(T x,U M){return (x%M+M)%M;}

typedef long long ll;

//output
template<typename T> ostream& operator << (ostream& os, const vector<T>& as){REP(i,as.size()){if(i!=0)os<<" "; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const vector<vector<T>>& as){REP(i,as.size()){if(i!=0)os<<endl; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const set<T>& ss){for(auto a:ss){if(a!=ss.begin())os<<" "; os<<a;}return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const pair<T1,T2>& p){os<<p.first<<" "<<p.second;return os;}
template<typename K,typename V> ostream& operator << (ostream& os, const map<K,V>& m){bool isF=true;for(auto& p:m){if(!isF)os<<endl;os<<p;isF=false;}return os;}
template<typename T1> ostream& operator << (ostream& os, const tuple<T1>& t){os << get<0>(t);return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const tuple<T1,T2>& t){os << get<0>(t)<<" "<<get<1>(t);return os;}
template<typename T1,typename T2,typename T3> ostream& operator << (ostream& os, const tuple<T1,T2,T3>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6,typename T7> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t)<<" "<<get<6>(t);return os;}


typedef int Cost; Cost CINF=1<<28;
struct Edge{
	int f,t;Cost c;
	Edge(int f,int t,Cost c) : f(f),t(t),c(c) {};
	bool operator<(Edge r) const{return c<r.c;}
	bool operator>(Edge r) const{return c>r.c;}
};
typedef vector<vector<Edge> >  Graph;

struct Task{
    int prev,pos;Cost c;
    Task(int prev,int pos,Cost c)
        :prev(prev),pos(pos),c(c){};
    bool operator>(const Task& r) const{ return c > r.c;}
};

vector<Cost> dijkstra(const Graph& g,const int s,vector<int>& prev){
    const int V=g.size();
    vector<Cost> d(V,CINF);d[s]=0;
    fill(ALL(prev), -2);
    
    priority_queue<Task,vector<Task>,greater<Task> > que;que.push(Task(-1,s,0));// [ ,e,,f, ] <=> e.cost < e.cost
    vector<bool> visited(V);
    while(!que.empty()){
        Task task=que.top();que.pop();
        if(visited[task.pos])continue;
        visited[task.pos]=true;
        prev[task.pos]=task.prev;
        EACH(e,g[task.pos])if(d[e->t]>d[e->f]+e->c){
            d[e->t]=d[e->f]+e->c;
            que.push(Task(e->f,e->t,d[e->t]));
        }   
    }
    return d;
}
vector<Cost> dijkstra(const Graph& g,const int s){
    vector<int> prev(g.size());return dijkstra(g,s,prev);
}


int main() {
	cout <<fixed<<setprecision(15);	
	cin.tie(0);
	ios::sync_with_stdio(false);

	while(true){
		int N,M,cap;cin >> N >> M >> cap;if(N==0)break;
		
		map<string,int> m;int S=0;
		int s;
		{
			string src;cin >> src;
			if(!m.count(src))m[src]=s=S++;
		}
		int t;
		{
			string dist;cin >> dist;
			if(!m.count(dist))m[dist]=t=S++;			
		}
		vector<tuple<int,int,int>> es;
		REP(i,N){
			string f,t;int c;cin >> f >> t >> c;
			if(!m.count(f))m[f]=S++;
			if(!m.count(t))m[t]=S++;
			es.emplace_back(m[f],m[t],c);
		}
		vector<int> ss;
		REP(i,M){
			string s;cin >>s;
			if(!m.count(s))m[s]=S++;
			ss.push_back(m[s]);
		}
		map<int,int> stoi;int I=0;
		if(!stoi.count(s))stoi[s]=I++;
		if(!stoi.count(t))stoi[t]=I++;
		REP(i,M)if(!stoi.count(ss[i])){
			stoi[ss[i]]=I++;
		}
		map<int,int> itoS;EACH(it,stoi)itoS[it->second]=it->first;

		Graph g(S);
		REP(i,N){
			// cerr << es[i] <<endl;
			g[get<0>(es[i])].emplace_back(get<0>(es[i]),get<1>(es[i]),get<2>(es[i]));
			g[get<1>(es[i])].emplace_back(get<1>(es[i]),get<0>(es[i]),get<2>(es[i]));
		}
		Graph gc(I);
		REP(i,I){
			vector<Cost> cs=dijkstra(g,itoS[i]);
			REP(j,S)if(stoi.count(j)){
				int ji=stoi[j];
				if(cs[j]<=10*cap)gc[i].emplace_back(i,ji,cs[j]);
			}
		}
		vector<Cost> cs=dijkstra(gc,s);

		if(cs[t]>=CINF) cout << -1<<endl;
		else cout << cs[t]<<endl;
	}

}

Measured memory_bytes: 3688