#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <functional>
#include <cassert>
using namespace std;

const int INF = (int)1e9;

struct Node {
  int v, cap, cost;
  Node(int v_, int cap_, int cost_) : v(v_), cap(cap_), cost(cost_) { }
  bool operator >(const Node &rhs) const {
    return cost > rhs.cost;
  }
};

struct Edge {
  int to, cost;
  Edge(int to_, int cost_) : to(to_), cost(cost_) { }
};

int main() {
  while(true) {
    int N, M, cap;
    cin >> N >> M >> cap;
    cap *= 10;
    if(N == 0 && M == 0) break;
    string src_s, dst_s;
    cin >> src_s >> dst_s;
    vector<pair<pair<string,string>,int>> edges;
    vector<string> names;
    for(int i = 0; i < N; ++i) {
      string c1_s, c2_s; int d;
      cin >> c1_s >> c2_s >> d;
      edges.push_back(make_pair(make_pair(c1_s, c2_s), d));
      names.push_back(c1_s);
      names.push_back(c2_s);
    }
    names.push_back(src_s);
    names.push_back(dst_s);
    sort(names.begin(), names.end());
    names.erase(unique(names.begin(), names.end()), names.end());
#if 0
    for(int i = 0; i < (int)names.size(); ++i) {
      cerr << "names[" << i << "] = " << names[i] << endl;
    }
#endif
    vector<vector<Edge>> graph(names.size());
    for(int i = 0; i < N; ++i) {
      int c1 = lower_bound(names.begin(), names.end(), edges[i].first.first) - names.begin();
      int c2 = lower_bound(names.begin(), names.end(), edges[i].first.second) - names.begin();
      int d = edges[i].second;
#if 1
      graph[c1].push_back(Edge(c2, d));
      graph[c2].push_back(Edge(c1, d));
#endif
    }
#if 0
    for(auto item : str2int) {
      cerr << item.first << " -> " << item.second << endl;
    }
    for(int i = 0; i < (int)graph.size(); ++i) {
      for(int j = 0; j < (int)graph[i].size(); ++j) {
        cerr << i << " " << graph[i][j].to << " " << graph[i][j].cost << endl;
      }
    }
#endif
    set<int> LPG;
    for(int i = 0; i < M; ++i) {
      string s; cin >> s;
      int k = lower_bound(names.begin(), names.end(), s) - names.begin();
      LPG.insert(k);
    }
    int src = lower_bound(names.begin(), names.end(), src_s) - names.begin();
    int dst = lower_bound(names.begin(), names.end(), dst_s) - names.begin();
    int V = names.size();
    names.clear();
    vector<vector<int>> D(V, vector<int>(cap+1, INF));
    priority_queue<Node, vector<Node>, greater<Node>> Q;
    D[src][cap] = 0;
    Q.emplace(src, cap, 0);
    while(!Q.empty()) {
      Node node = Q.top(); Q.pop();
      // cerr << "(" << node.v << "," << node.cap << "," << node.cost << ")" << endl;
      if(LPG.count(node.v)) {
        if(D[node.v][cap] > D[node.v][node.cap]) {
          D[node.v][cap] = D[node.v][node.cap];
          Q.emplace(node.v, cap, D[node.v][cap]);
        }
      }
      for(Edge &e : graph[node.v]) {
        int newcap = node.cap - e.cost;
        // cerr << "move " << e.to << " " << newcap << endl;
        if(newcap < 0) continue;
        if(D[e.to][newcap] > D[node.v][node.cap] + e.cost) {
          // cerr << "push" << endl;
          D[e.to][newcap] = D[node.v][node.cap] + e.cost;
          Q.emplace(e.to, newcap, D[e.to][newcap]);
        }
      }
    }
    int ans = INF;
    for(int i = 0; i <= cap; ++i) {
      ans = min(ans, D[dst][i]);
    }
    if(ans == INF) {
      cout << -1 << endl;
    }
    else {
      cout << ans << endl;
    }
  }
}

Measured memory_bytes: 51432