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

class Edge
{
public:
	int src,dst,cst;
	Edge(int src, int dst, int cst)
		:src(src),dst(dst),cst(cst)
	{}
};

class State
{
public:
	int p,c;
	State(int p, int c)
		:p(p),c(c)
	{}

	bool operator<(const State& s) const
	{
		return c > s.c;
	}
};

typedef vector<vector<Edge> > Graph;

int dijkstra(int S, int T, Graph& graph)
{
	bool vis[500] = {0};

	priority_queue<State> q;
	q.push(State(S, 0));

	while(!q.empty()) {
		State s = q.top(); q.pop();
		if(s.p == T) return s.c;

		if(vis[s.p]) continue;
		vis[s.p] = 1;

		for(int i=0; i<graph[s.p].size(); i++) {
			Edge& e = graph[s.p][i];
			if(vis[e.dst]) continue;

			q.push(State(e.dst, s.c + e.cst));
		}
	}

	return -1;
}

int main()
{
	int N,M;
	while(cin >> N >> M, (N||M)) {
		map<string, int> dic;
		int ncnt = 0;

		string a,b,c;
		cin >> a >> b >> c;
		if(!dic.count(a)) dic[a] = ncnt++;
		if(!dic.count(b)) dic[b] = ncnt++;
		if(!dic.count(c)) dic[c] = ncnt++;


		Graph graph(N);
		for(int i=0; i<M; i++) {
			string x,y;
			cin >> x >> y;

			int u,v;
			if(!dic.count(x)) dic[x] = ncnt++;
			if(!dic.count(y)) dic[y] = ncnt++;

			u = dic[x];
			v = dic[y];

			int c,t;
			cin >> c >> t;
			graph[u].push_back(Edge(u, v, c/40 + t));
			graph[v].push_back(Edge(v, u, c/40 + t));
		}

		int res = dijkstra(dic[a], dic[b], graph);
		res += dijkstra(dic[b], dic[c], graph);

		cout << res << endl;
	}
}