/*#include <cstdio>
#include <algorithm>
#include <limits>
#include <queue>
#include <vector>
#include <utility>
#define rep(i,a) for(int i=0;i<(a);++i)

constexpr int MAX_N = 200, MAX_R = 1000, INF = std::numeric_limits<int>::max()>>2;

struct edge
{
  int to, cost;
  bool ship;

  edge( int to, int cost, bool ship )
  : to(to), cost(cost), ship(ship)
  {}
};

struct State
{
  int dist, v, ord, shipP;

  State( int dist, int v, int ord, int shipP )
  : dist(dist), v(v), ord(ord), shipP(shipP)
  {}

  bool operator< ( const State &s ) const
  { return this->dist > s.dist; }
};

int N, M;
std::vector<edge> G[MAX_N];
int R;
int z[MAX_R];
short dp[MAX_N][MAX_R][MAX_N];

int main()
{
  while( scanf( "%d%d", &N, &M ), N|M )
  {
    rep( i, N )
      G[i].clear();

    rep( i, M )
    {
      int x, y, t;
      char sl;
      scanf( "%d%d%d %c", &x, &y, &t, &sl );
      --x; --y;
      //putchar(sl);
      G[x].push_back( edge( y, t, sl=='S' ) );
      G[y].push_back( edge( x, t, sl=='S' ) );
    }

    scanf( "%d", &R );
    rep( i, R )
      scanf( "%d", z+i ), --z[i];

    std::priority_queue<State> pque;
    pque.push( State( 0, z[0], 0, 0 ) );
    std::fill( (int*)dp, (int*)(dp+N), INF );
    dp[z[0]][0][0] = 0;

    while( !pque.empty() )
    {
      State st = pque.top(); pque.pop();

      if( st.dist > dp[st.v][st.ord][st.shipP] || st.ord == R-1 )
        continue;

      //printf( "[%d %d %d %d]\n", st.dist, st.v, st.ord, st.shipP );

      for( auto e : G[st.v] )
      {
        int nord = e.to == z[st.ord+1] ? st.ord+1 : st.ord;
        
        if( st.shipP == st.v && e.ship && dp[e.to][nord][e.to] > dp[st.v][st.ord][st.shipP]+e.cost )
        {
          dp[e.to][nord][e.to] = dp[st.v][st.ord][st.shipP]+e.cost;
          pque.push( State( dp[e.to][nord][e.to], e.to, nord, e.to ) );
        }

        if( !e.ship && dp[e.to][nord][st.shipP] > dp[st.v][st.ord][st.shipP]+e.cost )
        {
          dp[e.to][nord][st.shipP] = dp[st.v][st.ord][st.shipP]+e.cost;
          pque.push( State( dp[e.to][nord][st.shipP], e.to, nord, st.shipP ) );
        }
      }
    }

    short ans = INF;
    rep( i, N )
      ans = std::min( ans, dp[z[R-1]][R-1][i] );

    printf( "%d\n", ans );
  }

  return 0;
}*/

#include <cstdio>
#include <algorithm>
#define rep(i,a) for(int i=0;i<(a);++i)

constexpr int MAX_N = 200, MAX_R = 1000, INF = std::numeric_limits<int>::max()>>2;

int N, M;
int sea[MAX_N][MAX_N], land[MAX_N][MAX_N];
int R;
int z[MAX_R];
int dp[MAX_R+1][MAX_N];

int main()
{
  while( scanf( "%d%d", &N, &M ), N|M )
  {
    std::fill( (int*)sea, (int*)(sea+N), INF );
    std::fill( (int*)land, (int*)(land+N), INF );

    rep( i, N )
      sea[i][i] = land[i][i] = 0;

    rep( i, M )
    {
      int x, y, t;
      char sl;
      scanf( "%d%d%d %c", &x, &y, &t, &sl );
      --x; --y;

      if( sl == 'S' )
      {
        sea[x][y] = std::min( sea[x][y], t );
        sea[y][x] = std::min( sea[y][x], t );
      }
      else
      {
        land[x][y] = std::min( land[x][y], t );
        land[y][x] = std::min( land[y][x], t );
      }
    }

    scanf( "%d", &R );

    rep( i, R )
      scanf( "%d", z+i ), --z[i];

    rep( k, N ) rep( i, N ) rep( j, N )
    {
      sea[i][j] = std::min( sea[i][j], sea[i][k]+sea[k][j] );
      land[i][j] = std::min( land[i][j], land[i][k]+land[k][j] );
    }

    std::fill( (int*)dp, (int*)(dp+R), INF );
    dp[0][z[0]] = 0;

    rep( i, R-1 ) rep( j, N )
    {
      dp[i+1][j] = std::min( dp[i+1][j], dp[i][j]+land[z[i+1]][z[i]] );

      rep( k, N )
        dp[i+1][k] = std::min( dp[i+1][k], dp[i][j]+land[z[i]][j]+sea[j][k]+land[z[i+1]][k] );
    }

    printf( "%d\n", *std::min_element( dp[R-1], dp[R-1]+N ) );
  }

  return 0;
}


Measured memory_bytes: 3808