#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <tuple>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <limits>

using Bool = bool;
using Int = long long int;
using String = std::string;
template <class... Ts>
using Tuple = std::tuple<Ts...>;
template <class T>
using Vector = std::vector<T>;
template <class T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T>
using Set = std::set<T>;
template <class T, class U>
using Map = std::map<T, U>;

template <class Cost = Int>
struct Edge {
    Int src, dst;
    Cost cost;
    Edge(Int src = -1, Int dst = -1, Cost cost = 1)
        : src(src), dst(dst), cost(cost){};

    bool operator<(const Edge<Cost>& e) const { return this->cost < e.cost; }
    bool operator>(const Edge<Cost>& e) const { return this->cost > e.cost; }
};
template <class Cost = Int>
using Graph = Vector<Vector<Edge<Cost>>>;

constexpr Int INF = std::numeric_limits<Int>::max() / 3;

Bool solve() {
    Int m, l, cap;
    std::cin >> m >> l >> cap;
    if (m == 0) return false;
    cap *= 10;

    String ss, gs;
    std::cin >> ss >> gs;

    Int n;
    Graph<Int> graph;

    Map<String, Int> rev;

    {
        Vector<String> strs;
        Vector<Tuple<String, String, Int>> edges(m);
        for (auto& e : edges) {
            String us, vs;
            Int d;
            std::cin >> us >> vs >> d;
            e = std::make_tuple(us, vs, d);
            strs.push_back(us), strs.push_back(vs);
        }

        std::sort(strs.begin(), strs.end());
        strs.erase(std::unique(strs.begin(), strs.end()), strs.end());
        n = strs.size();
        for (Int i = 0; i < n; ++i) rev[strs[i]] = i;

        graph.resize(n);
        for (auto& e : edges) {
            String us, vs;
            Int d;
            std::tie(us, vs, d) = e;
            Int u = rev[us], v = rev[vs];

            graph[u].emplace_back(u, v, d);
            graph[v].emplace_back(v, u, d);
        }
    }

    Int s = rev[ss], g = rev[gs];

    Set<Int> tanks;
    for (Int i = 0; i < l; ++i) {
        String vs;
        std::cin >> vs;
        tanks.insert(rev[vs]);
    }

    Vector<Vector<Int>> dist(n, Vector<Int>((cap + 1), INF));
    dist[s][cap] = 0;
    MinHeap<Tuple<Int, Int, Int>> heap;
    heap.emplace(0, s, cap);

    while (!heap.empty()) {
        Int d, v, c;
        std::tie(d, v, c) = heap.top();
        heap.pop();
        if (dist[v][c] < d) continue;

        for (auto e : graph[v]) {
            if (e.cost > c ||
                dist[e.dst][c - e.cost] <= dist[e.src][c] + e.cost) continue;
            dist[e.dst][c - e.cost] = dist[e.src][c] + e.cost;
            heap.emplace(dist[e.dst][c - e.cost], e.dst, c - e.cost);
        }

        if (tanks.count(v) && dist[v][cap] > dist[v][c]) {
            dist[v][cap] = dist[v][c];
            heap.emplace(dist[v][cap], v, cap);
        }
    }

    Int ans = *std::min_element(dist[g].begin(), dist[g].end());

    std::cout << (ans < INF ? ans : -1) << std::endl;
    return true;
}

int main() {
    while (solve()) {}
    return 0;
}

