#include<iostream>
#include <list>
#include<stack>
#include<queue>
#include <vector>
#include <set>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
#include<string>
#include <functional>
#include<fstream>
#include<iomanip>
#include<array>

#define FOR(k,m,n) for(int (k)=(m);(k)<(n);(k)++)
#define REP(i,n) FOR((i),0,(n))
#define LL long long
#define CLR(a) memset((a),0,sizeof(a))
#define SZ(x) (int((x).size()))
#define WAITING(str) int str;std::cin>>str;
#define DEBUGING(str) cout<<str<<endl
using namespace std;

const LL MOD = 1000000007;// 10^9+7
constexpr int INF = (1 << 25);
constexpr int siz = 200;


//名前の通り。　N個の独立した要素を併合するときに使用
class UnionFind {
public:
	vector<int>rank, parent;
	//初期化
	UnionFind(int size) {
		rank.resize(size, 0);
		parent.resize(size, 0);
		REP(i, size)parent[i] = i;
	}
	//木の根を求める
	int find(int x) {
		if (parent[x] == x)return x;
		else return parent[x] = find(parent[x]);
	}
	//xとyの属する集合を併合
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y)return;
		if (rank[x] < rank[y])
			parent[x] = y;
		else {
			parent[y] = x;
			if (rank[x] == rank[y])rank[x]++;
		}
	}
	//xとyが同じ集合に属するか否か
	bool same(int x, int y) {
		return (find(x) == find(y));
	}
	//parentの内容を出力
	void debug() {
		for (auto num : parent) {
			cout << num << " ";
		}
		cout << "more:" << endl;
		REP(i, parent.size()) {
			cout << find(i) << " ";

		}
		cout << endl << "more:" << endl;
		for (auto num : parent) {
			cout << num << " ";
		}
		cout << endl;
	}
};

struct Stage{
	Stage(){
		cin >> N >> M;
		if (!N)return;

		int x, y, t;
		string sl;
		for (auto& v : load)fill(v.begin(), v.end(), INF);
		for (auto& v : sea)fill(v.begin(), v.end(), INF);
		fill(havePort.begin(), havePort.end(), false);
		REP(i, N)load[i][i] = sea[i][i] = 0;
		REP(i, M)
		{
			cin >> x >> y >> t >> sl;
			x--; y--;
			if (sl == "L") {
				load[x][y] = load[y][x] = t;
				uf.unite(x, y);
			}
			else {
				sea[x][y] = sea[y][x] = t;
				havePort[x] = havePort[y] = true;
			}
		}

		int R;cin >> R;
		REP(i, R)
		{
			cin >> t;
			t--;
			z.push_back(t);
		}
	}
	
	bool is_end(){
		return N == 0;
	}
	
	void action()
	{
		warshall_floyd(load);
		warshall_floyd(sea);
		
		vector<vector<int>> dp(z.size(), vector<int>(N, INF));
		dp[0][z[0]] = 0;
		FOR(i, 1, z.size()){
			//陸路
			REP(j, N)
			{
				dp[i][j] = min(dp[i][j], dp[i - 1][j] + load[z[i]][z[i - 1]]);
			}

			//海路
			REP(j, N) if (havePort[j] && uf.same(j, z[i]))
				REP(k, N) if (havePort[k] && uf.same(k, z[i - 1]))
			{
				int fromL = z[i - 1];
				int fromS = k;
				int toS = j;
				int toL = z[i];

				int befTime = dp[i - 1][k];
				int timeLS = load[fromL][fromS];
				int timeSS = sea[fromS][toS];
				int timeSL = load[toS][toL];

				if (max(max(befTime, timeLS), max(timeSS, timeSL)) == INF)
					continue;
				dp[i][j] = min(dp[i][j], befTime + timeLS + timeSS + timeSL);
			}

		}
		
		cout << *min_element(dp.back().begin(), dp.back().end()) << endl;

		/*
		int bef = 0;
		int now = 0;
		fill(time.begin(), time.end(), INF);
		time[z[0]] = 0;

		warshall_floyd(load);
		warshall_floyd(sea);

		while (now < z.size()) {
			vector<int> route;
			while (now < z.size() && uf.same(bef, now)) {
				route.push_back(now);
				now++;
			}
			bef = now;
			update(route);
		}
		
		int res = INF;
		REP(i, N)if (uf.same(i, z.back()))
		{
			res = min(res, time[i] - load[i][z.back()]);
		}
		cout << res << endl;
		*/
	}
	
private:
	int N, M;
	UnionFind uf = UnionFind(siz);//陸のセット作成
	array<int, siz> time;
	array<bool, siz> havePort;
	array<array<int, siz>, siz> load, sea;	
	vector<int> z;
	
	void warshall_floyd(array<array<int, siz>,siz>& edge)
	{
		REP(k, siz)REP(i, siz)REP(j, siz)
			if (edge[i][k] != INF && edge[j][k] != INF)
				edge[i][j] = min(edge[i][j], edge[i][k] + edge[k][j]);
	}

	void update(vector<int> route)
	{
		array<int, siz> besttime;
		fill(besttime.begin(), besttime.end(), INF);
		REP(port, N)
			if (havePort[port] && uf.same(route.back(),port)) 
			{
				besttime[port] = act_route(port, route);
			}
		time = besttime;
	}

	int act_route(
		const int& port, 
		const vector<int>& route)
	{
		int best = INF;
		REP(i, N)if (time[i] != INF)
		{
			int sum = time[i];
			sum += sea[i][port];
			REP(j, route.size() - 1)
			{
				sum += load[route[i]][route[i + 1]];
			}
			sum += load[route.back()][port];
			best = min(best, sum);
		}
		return best;
	}
};

//デバッグ
void debug()
{
	int N;
	cin>>N;
}


//メイン関数
int main()
{
	while(true){
		Stage stage;
		if(stage.is_end())break;
		stage.action();
	}
	debug();
	
	return 0;
}



Measured memory_bytes: 3956