Problem:
Problem D:
Mr. Rito Post Office
あなたは離島の郵便局に勤めるプログラマである．あなたの住んでいる地域は，複数の島々からなる．各島には一つ以上の港町がある．それらに加えて他の町や村があるかもしない．ある島から別の島に向かうためには船を使わなければならない．一つの島の中を回るには陸路が使えるが，海路を利用した方が速いこともある．
近年行われた郵便局の民営化をきっかけに，経費削減に向けて郵便配達員の人員整理が全国的に行われた．離島の郵便局もその例外ではなく，結果として郵便配達員は利藤さんただ一人となってしまった．その郵便局が集配を担当する地域は非常に広いため，一人で集配するのは大変な作業である．なので，どのようにすれば効率的に集配を行えるのか，利藤さんがあなたに助けを求めてきた．
あなたの仕事は，利藤さんがたどるべき町や村の集配順序が与えられたときに，最短巡回経路を求めるプログラムを書くことである．
利藤さんは，決して指定された順序以外で集配業務を行うことができない．しかし，ある町や村から別の町や村へ移動する際に，他の町や村を経由して移動することは許可されている．また，利藤さんは島々を巡るための一隻の船を持っている．
例えば，町A，町B，村Cという集配順序が与えられた場合，町Aから町Bへ向かう際にどの町や村を経由してもかまわない．このとき，村Cを経由しても構わないが，集配順序を守るためには，一度町Bに行って集配をおこなってから，改めて村Cを訪れて集配をおこなわなければならない．また，町Aから海路を用いて町Bに向かい，町Bから陸路を用いて村Cに向かった場合，船を町Bに置いたままになる．したがって，次に海路を使いたい場合は町Bに戻る必要がある．
一つの町や村において複数回集配をしなければならない場合もある．たとえば，町A，村B，町C，村Bという集配順序が与えられるかもしれない．このとき，町Aから村Bをたどらずに町Cに向かった場合は，町Cでいきなり集配をおこなうことはできない．最初の村Bでの集配が終わっていないからである．町Cで集配を済ませた後で村Bを訪れて集配しても，一回目の村Bの集配を終わらせたことにはならない．
利藤さんは，はじめに必ずある港町に船とともにいる．利藤さんはベテランであるため，移動時間以外の集配作業にかかる時間は無視してよい．また，最後の町または村での集配業務が完了するまでの時間だけが問題であり，船をもとの位置に戻して郵便局に帰るまでの時間は考慮しなくてよい．
Input
入力は複数のデータセットから構成される．各データセットの形式は次に示すとおりである．
N
M
x
1
y
1
t
1
sl
1
x
2
y
2
t
2
sl
2
...
x
M
y
M
t
M
sl
M
R
z
1
z
2
...
z
R
データセットの中の入力項目は，すべて非負の整数である．行中の入力項目の区切りは空白 1 個である．
最初の行は，陸路及び海路網の大きさを規定する．
N
(2 ≤
N
≤ 200) は，町または村の数である． 
それぞれの町または村には，1 から
N
までの固有の番号を割り当てる．
M
(1 ≤
M
≤ 10000) は，陸路と海路の合計本数である．
2 行目から 1 +
M
行目は，陸路または海路の記述である．
x
i
と
y
i
(1 ≤
x
i
,
y
i
≤
N
) は両端の町または村の番号を表す．
t
i
(1 ≤
t
i
≤ 1000) はその陸路または海路の移動時間を表す．
sl
i
は ‘L’ または ‘S’ のいずれかであり，Lは陸路を，Sは海路をそれぞれ表す．
ある2つの町や村を直接結ぶ陸路または海路が2本以上存在することがある． それぞれの陸路または海路は双方向であり，すなわちどちらの向きにも移動できる．
M
+ 2 行目の
R
(1 ≤
R
≤
1000)は，利藤さんが担当する集配先の数を表す．
M
+ 3 行目には，集配先の町や村の番号
z
i
(1 ≤
z
i
≤
N
) が集配順に
R
個並んでいる．
初期状態では利藤さんと船はともに港町
z
1
に存在する． 初期状態から集配先の町や村へは，必ず何らかの方法で移動することができる．
入力の終わりは，空白で区切られた2つの0を含む1行で示される．
Output
入力の各データセットに対して，与えられた集配順序で利藤さんが町と村を巡回するために必要な最短移動時間を求め，1行に出力せよ．
Sample Input
3 3
1 2 5 L
1 2 7 S
2 3 11 S
3
1 2 3
5 5
1 2 15 L
2 3 10 L
4 5 7 L
1 3 30 S
3 4 100 S
5
1 3 5 4 1
0 0
Output for the Sample Input
18
269

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
        int d[2010][202];
        int l[202][202];
        int s[202][202];
        memset(d,0x3f,sizeof(d));
        memset(l,0x3f,sizeof(l));
        memset(s,0x3f,sizeof(s));
        for(int i=0;i<m;i++){
            int x,y,t;
            char ch[3];
            scanf("%d%d%d%s",&x,&y,&t,ch);
            if(ch[0]=='L'){
                l[x][y]=min(l[x][y],t);
                l[y][x]=min(l[y][x],t);
            }else{
                s[x][y]=min(s[x][y],t);
                s[y][x]=min(s[y][x],t);
            }
        }
        int init;
        int r;
        scanf("%d",&r);
        vector<int> g;
        g.push_back(0);
        scanf("%d",&init);
        g.push_back(init);
        for(int i=1;i<r;i++){
            int x;
            scanf("%d",&x);
            g.push_back(x);
        }
        for(int i=1;i<=n;i++){
            l[i][i]=s[i][i]=0;
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
                    l[i][j]=min(l[i][j],l[i][k]+l[k][j]);
                }
            }
        }
        for(int i=1;i<=n;i++){
            d[1][i]=min(d[1][i],s[g[1]][i]+l[g[1]][i]);
        }
        for(int i=1;i<=r;i++){
            for(int j=1;j<=n;j++){
                if(l[g[i]][j]>=INF) continue;
                for(int k=1;k<=n;k++){
                    if(l[g[i-1]][k]>=INF) continue;
                    if(j==k){
                        if(l[g[i-1]][g[i]]!=INF){
                            d[i][j]=min(d[i][j],d[i-1][j]+l[g[i-1]][g[i]]);
                        }
                    }else{
                        if(l[g[i-1]][k]!=INF&&s[k][j]!=INF&&l[j][g[i]]!=INF){
                            d[i][j]=min(d[i][j],d[i-1][k]+l[g[i-1]][k]+s[k][j]+l[j][g[i]]);
                        }
                    }
                }
            }
        }
        int ans=INF;
        for(int i=1;i<=n;i++){
            ans=min(ans,d[r][i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 5380
final_rank: 16

code_snippet: //
//  AOJ 2200 Mr. Rito Post Office
//
//  Created by TaoSama on 2015-03-20
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#define CLR(x,y) memset(x, y, sizeof(x))

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

int sea[205][205], land[205][205], dp[1005][205];
int n, m, r, a[1005];

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(cin >> n >> m && (n + m)) {
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                sea[i][j] = land[i][j] = i == j ? 0 : INF;

        for(int i = 1; i <= m; ++i) {
            int x, y, t; char c;
            cin >> x >> y >> t >> c;
            if(c == 'S') sea[x][y] = sea[y][x] = min(sea[x][y], t);
            else land[x][y] = land[y][x] = min(land[x][y], t);
        }

        cin >> r;
        for(int i = 1; i <= r; ++i)  cin >> a[i];


        for(int k = 1; k <= n; ++k) {
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= n; ++j) {
                    sea[i][j] = min(sea[i][j], sea[i][k] + sea[k][j]);
                    land[i][j] = min(land[i][j], land[i][k] + land[k][j]);
                }
            }
        }


        memset(dp, 0x3f, sizeof dp);
        dp[1][a[1]] = 0;
        for(int i = 1; i <= r; ++i) {
            for(int j = 1; j <= n; ++j) {
                dp[i][j] = min(dp[i][j], dp[i - 1][j] + land[a[i - 1]][a[i]]);
                for(int k = 1; k <= n; ++k)
                    dp[i][k] = min((long long)dp[i][k], (long long)dp[i - 1][j] +
                                   land[a[i - 1]][j] + sea[j][k] + land[k][a[i]]);
            }
        }
        cout << *min_element(dp[r]+1, dp[r] + n + 1) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 4596
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

void solve(int N, int M) {
    vector<vector<int>> L(N, vector<int>(N, INF)), S(N, vector<int>(N, INF));
    for (int i = 0; i < N; i++) L[i][i] = S[i][i] = 0;
    for (; M--;) {
        int x, y, t;
        char sl;
        cin >> x >> y >> t >> sl;
        x--, y--;
        if (sl == 'L') {
            L[x][y] = min(L[x][y], t);
            L[y][x] = min(L[y][x], t);
        } else {
            S[x][y] = min(S[x][y], t);
            S[y][x] = min(S[y][x], t);
        }
    }
    int R;
    cin >> R;
    vector<int> z(R);
    for (int& x : z) cin >> x, x--;

    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                L[i][j] = min(L[i][j], L[i][k] + L[k][j]);
                S[i][j] = min(S[i][j], S[i][k] + S[k][j]);
            }
        }
    }

    vector<int> dp(N, INF), ndp(N, INF);
    dp[z[0]] = 0;
    auto calc = [&](int pre, int nxt) {
        vector<int> join(N, INF);
        for (int i = 0; i < N; i++) {
            join[i] = min(join[i], dp[i] + L[pre][i]);
            ndp[i] = min(ndp[i], dp[i] + L[pre][nxt]);
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                join[j] = min(join[j], join[i] + S[i][j]);
            }
        }
        for (int i = 0; i < N; i++) {
            ndp[i] = min(ndp[i], join[i] + L[i][nxt]);
            dp[i] = INF;
        }
        swap(dp, ndp);
    };

    for (int i = 0; i + 1 < R; i++) calc(z[i], z[i + 1]);
    int ans = INF;
    for (int i = 0; i < N; i++) ans = min(ans, dp[i]);
    cout << ans << '\n';
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N, M;
    while (cin >> N >> M, N) solve(N, M);
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 3520
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

constexpr int N = 200;
long long gl[200][200];
long long gs[200][200];
int n, m, r;

void floyd(long long (&g)[200][200]) {
    for (int k = 0; k < n; ++k) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (g[i][k] == LLONG_MAX || g[k][j] == LLONG_MAX) continue;
                g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
            }
        }
    }
}

void solve() {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i == j) {
                gl[i][j] = 0;
                gs[i][j] = 0;
                continue;
            }
            gl[i][j] = LLONG_MAX;
            gs[i][j] = LLONG_MAX;
        }
    }
    for (int i = 0; i < m; ++i) {
        int a, b;
        long long c;
        char sl;
        cin >> a >> b >> c >> sl;
        --a, --b;
        if (sl == 'L') {
            gl[a][b] = min(gl[a][b], c);
            gl[b][a] = min(gl[b][a], c);
        } else {
            gs[a][b] = min(gs[a][b], c);
            gs[b][a] = min(gs[b][a], c);
        }
    }

    // for (int i = 0; i < n; ++i) {
    //     for (int j = 0; j < n; ++j) {
    //         cout << gl[i][j] << " ";
    //     }
    //     cout << '\n';
    // }

    // cout << "---\n";

    floyd(gl);
    floyd(gs);

    // for (int i = 0; i < n; ++i) {
    //     for (int j = 0; j < n; ++j) {
    //         cout << gl[i][j] << " ";
    //     }
    //     cout << '\n';
    // }

    // cout << "---\n";

    cin >> r;
    vector<long long> dp(n, LLONG_MAX);
    vector<long long> new_dp(n, LLONG_MAX);
    int last_lpos;
    cin >> last_lpos;
    --last_lpos;
    dp[last_lpos] = 0;

    for (int i = 1; i < r; ++i) {
        int lpos;
        cin >> lpos;
        --lpos;
        for (int spos = 0; spos < n; ++spos) {
            new_dp[spos] = LLONG_MAX;
            for (int last_spos = 0; last_spos < n; ++last_spos) {
                long long d;

                if (last_spos == spos) {
                    if (dp[last_spos] == LLONG_MAX) continue;
                    if (gl[last_lpos][lpos] == LLONG_MAX) continue;
                    d = dp[last_spos] + gl[last_lpos][lpos];
                } else {
                    if (dp[last_spos] == LLONG_MAX) continue;
                    if (gl[last_lpos][last_spos] == LLONG_MAX) continue;
                    if (gs[last_spos][spos] == LLONG_MAX) continue;
                    if (gl[spos][lpos] == LLONG_MAX) continue;
                    d = dp[last_spos] + gl[last_lpos][last_spos] +
                        gs[last_spos][spos] + gl[spos][lpos];
                }
                new_dp[spos] = min(new_dp[spos], d);
            }
        }
        last_lpos = lpos;
        swap(dp, new_dp);
    }

    long long ans = LLONG_MAX;
    for (int i = 0; i < n; ++i) {
        ans = min(ans, dp[i]);
    }
    cout << ans << endl;
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif

    while (true) {
        cin >> n >> m;
        if (n == 0 && m == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 350
memory_kb: 3980
final_rank: 11

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var) do { cout << #var << " :\n"; view(var); } while(0)
template<typename T>void view(const T& e) {cout << e;}
template<typename T1, typename T2>void view(const pair<T1, T2>& p) {cout << "{" << p.first << ", " << p.second << "}";}
template<typename T>void view(const vc<T>& v) {for (const auto& e : v) {view(e);cout << " ";} cout << endl;}
template<typename T>void view(const vv<T>& vv) {for (const auto& v : vv) {view(v);cout << " ";} cout << endl;}
template<typename T>void view(const set<T>& s) {for (const auto& e : s) {view(e);cout << " ";} cout << endl;}
template<typename T>void view(const unordered_set<T>& s) {for (const auto& e : s) {view(e);cout << " ";} cout << endl;}
template<typename T1, typename T2>void view(const map<T1, T2>& mp){for (const auto& e : mp) {view(e);cout << " ";} cout << endl;}

int N, M;
void solve(){
    vvl riku(N, vl(N, INF)), umi(N, vl(N, INF));
    rep(i, N){
        riku[i][i] = 0;
        umi[i][i] = 0;
    }
    rep(i, M){
        int x, y; ll t; char sl; cin >> x >> y >> t >> sl; x--; y--;
        if (sl == 'L'){
            riku[x][y] = min(riku[x][y], t);
            riku[y][x] = min(riku[y][x], t);
        }else{
            umi[x][y] = min(umi[x][y], t);
            umi[y][x] = min(umi[y][x], t);
        }
    }
    for (int k = 0; k < N; k++) for (int i = 0; i < N; i++) for (int j = 0; j < N; j++){
        if (riku[i][k] != INF && riku[k][j] != INF){
            if (riku[i][j] > riku[i][k] + riku[k][j]){
                riku[i][j] = riku[i][k] + riku[k][j];
            }
        }
        if (umi[i][k] != INF && umi[k][j] != INF){
            if (umi[i][j] > umi[i][k] + umi[k][j]){
                umi[i][j] = umi[i][k] + umi[k][j];
            }
        }
    }
    int R; cin >> R;
    vi Z(R); rep(i, R) cin >> Z[i];
    rep(i, R) Z[i]--;
    vvl dp(R, vl(N, INF));
    dp[0][Z[0]] = 0;
    srep(i, 1, R) rep(j, N){
        rep(nj, N) if (riku[Z[i - 1]][nj] < INF && umi[nj][j] < INF && riku[j][Z[i]] < INF) dp[i][j] = min(dp[i][j], dp[i - 1][nj] + riku[Z[i - 1]][nj] + umi[nj][j] + riku[j][Z[i]]);
        dp[i][j] = min(dp[i][j], dp[i - 1][j] + riku[Z[i - 1]][Z[i]]);
    }
    cout << accumulate(all(dp[R - 1]), INF,  [&](auto i, auto j){return min(i, j);}) << endl;
}

int main(){
    while (true){
        cin >> N >> M;
        if (N == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 220
memory_kb: 5632
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return false;
    vector<vector<long long>> L(N, vector<long long>(N, 1LL << 58));
    vector<vector<long long>> S(N, vector<long long>(N, 1LL << 58));
    while (M--) {
        int u, v, w;
        char c;
        cin >> u >> v >> w >> c;
        u--, v--;
        auto &D = (c == 'L' ? L : S);
        D[u][v] = min<long long>(D[u][v], w);
        D[v][u] = min<long long>(D[v][u], w);
    }
    for (int i = 0; i < N; i++) L[i][i] = S[i][i] = 0;
    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                L[i][j] = min(L[i][j], L[i][k] + L[k][j]);
                S[i][j] = min(S[i][j], S[i][k] + S[k][j]);
            }
        }
    }
    vector<long long> dp(N, 1LL << 58);
    int R, u;
    cin >> R >> u;
    u--;
    dp[u] = 0;
    while (--R) {
        int v;
        cin >> v;
        v--;
        vector<long long> ep(N, 1LL << 58);
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                ep[j] = min<long long>(ep[j], dp[i] + L[u][i] + S[i][j] + L[j][v]);
                ep[j] = min<long long>(ep[j], dp[j] + L[u][v]);
            }
        }
        dp = ep;
        u = v;
    }
    cout << *min_element(dp.begin(), dp.end()) << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 230
memory_kb: 4096
final_rank: 8

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG // 配列外参照のエラー
#endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 多倍長整数
//  #if __has_include(<boost/multiprecision/cpp_int.hpp>)
//  #include <boost/multiprecision/cpp_int.hpp>
//  using lll =boost::multiprecision::int128_t;
//  #endif

// atcoder関連
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
using mint = modint998244353;
using MINT = modint1000000007;
#endif

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
template <class T> using prique = priority_queue<T>;

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int inf = 2e9;
ll INF = 1e18;
#define endl '\n';

// 新規マクロ
#define all(a) (a).begin(), (a).end()
#define rep(i, N, limit) for (int i = (int)N; i < (int)limit; i++)

///////////////////// vector関連
// template <class T, size_t n, size_t idx = 0>
// auto make_vec(const size_t (&d)[n], const T &init) noexcept {
//     if constexpr (idx < n)
//         return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
//     else
//         return init;
// }

template <class T, size_t n> auto make_vec(const size_t (&d)[n]) noexcept {
    return make_vec(d, T{});
}

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

////////////////////////////
inline string input();
inline ll I();
inline pll II();

/////////////////////出力関連
inline void Yes(bool f);

bool solve() {
    int N, M;
    cin >> N >> M;
    if (N == 0) {
        return false;
    }
    vector<vector<ll>> EL = vector<vector<ll>>(N, vector<ll>(N, INF));
    vector<vector<ll>> ES=vector<vector<ll>>(N,vector<ll>(N,INF));
    
    for (int i = 0; i < N; i++) {
        EL[i][i] = 0;
        ES[i][i] = 0;
    }
    for (int i = 0; i < M; i++) {
        int x, y;
        ll t;
        char sl;
        cin >> x >> y >> t >> sl;
        x--;
        y--;
        if (sl == 'L') {
            EL[x][y] = min(EL[x][y], t);
            EL[y][x] = min(EL[y][x], t);
        } else {
            ES[x][y] = min(ES[x][y], t);
            ES[y][x] = min(ES[y][x], t);
        }
    }

    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                EL[i][j]=min(EL[i][j],EL[i][k]+EL[k][j]);
                ES[i][j]=min(ES[i][j],ES[i][k]+ES[k][j]);
            }
        }
    }

    int R;
    cin >> R;
    vector<int> Z(R);
    for (int i = 0; i < R; i++) {
        cin >> Z[i];
        Z[i]--;
    }

    vector<vector<ll>> dp = vector<vector<ll>>(R, vector<ll>(N, INF));
    
    dp[0][Z[0]]=0;
    for (int i = 0; i < R - 1; i++) {
        for (int j = 0; j < N; j++) {
            if (dp[i][j] == INF) {
                continue;
            }
            dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + EL[Z[i]][Z[i + 1]]);

            for (int k = 0; k < N; k++) {
                dp[i+1][k]=min(dp[i+1][k],dp[i][j]+EL[Z[i]][j]+ES[j][k]+EL[k][Z[i+1]]);
            }
        }
    }
    ll ans = INF;
    for (int i = 0; i < N; i++) {
        ans=min(ans,dp[R-1][i]);
    }
    print(ans);

    return true;
}

///////////////////ここから//////////////////////
int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve());
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

/////////////////////初期化///////////////////////

inline string input() {
    string S;
    cin >> S;
    return S;
}
inline ll I() {
    ll ret;
    cin >> ret;
    return ret;
}
inline pll II() {
    pll ret;
    cin >> ret.first >> ret.second;
    return ret;
}

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 2930
memory_kb: 5888
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<(n);i++)
#define REP2(i, n) for (ll i=0;i<(n);i++)
#define REP3(i, a, n) for (ll i=a;i<(n);i++)
#define REP4(i, a, b, n) for(ll i=a;i<(n);i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=(n)-1;i>=0;i--)
#define RREP2(i, n) for(ll i=(n)-1;i>=0;i--)
#define RREP3(i, a, n) for(ll i=(n)-1;i>=(a);i--)
#define RREP4(i, a, b, n) for(ll i=(n)-1;i>=(a);i-=(b))
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;

ll intpow(ll a,ll b){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
        }
        a *= a;
        b /= 2;
    }
    return ans;
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b >>= 1;
    }
    return ans;
}

template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}

#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i + 1 < vec.size()) os << ", ";
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::pair<T1, T2>>& a) {
    os << "[";
    for (size_t j = 0; j < a.size(); ++j) {
        os << "(" << a[j].first << ", " << a[j].second << ")";
		if (j + 1 < a.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<std::pair<T1, T2>>>& mat) {
	os << "[";
    for (size_t i = 0; i < mat.size(); ++i) {
		os << "[";
        for (size_t j = 0; j < mat[i].size(); ++j) {
            os << "(" << mat[i][j].first << ", " << mat[i][j].second << ")";
			if (j + 1 < mat[i].size()) os << ", ";
        }
		os << "]";
		if (i + 1 < mat.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::set<T>& s) {
    os << "{";
    bool first = true;
    for (const auto& x : s) {
        if (!first) os << ", ";
        os << x;
        first = false;
    }
    os << "}";
    return os;
}

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m) {
    os << "{";
    bool first = true;
    for (const auto& [key, val] : m) {
        if (!first) os << ", ";
        os << key << ": " << val;
        first = false;
    }
    os << "}";
    return os;
}

template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}

void write(){cout << "\n";}
template<class T, class... Ts>
void write(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void write(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vi x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvi x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvi x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vld x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvld x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvld x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vc x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvc x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << "";}else{cout << '\n';}}}
void write(vvvc x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vs x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << "\n";}else{cout << '\n';}}}
void write(vvs x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvs x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(pll x){cout << x.first << ' ' << x.second << '\n';}
void write(vpll x){rep(i,len(x)){cout << x[i].first << ' ' << x[i].second << '\n';}}
void write(vvpll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j].first << ' ' << x[i][j].second;if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

template <typename T>
T sum(const std::vector<T>& v) {
    return std::accumulate(v.begin(), v.end(), T(0));
}

template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }

int main(){
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while(1){
        LL(n,m);
        if(n + m == 0){break;}
        vvpll land_edge(n);
        vvpll sea_edge(n);
        vvll land_dist(n,vll(n,1LL<<60));
        vvll sea_dist(n,vll(n,1LL<<60));
        rep(i,m){
            LL(x,y,t);
            CHA(c);
            x--;
            y--;
            if(c == 'L'){
                land_edge[x].emplace_back(y,t);
                land_edge[y].emplace_back(x,t);
                chmin(land_dist[x][y],t);
                chmin(land_dist[y][x],t);
            }
            else{
                sea_edge[x].emplace_back(y,t);
                sea_edge[y].emplace_back(x,t);
                chmin(sea_dist[x][y],t);
                chmin(sea_dist[y][x],t);
            }
        }
        LL(r);
        VLL(z,r);
        rep(i,r){
            z[i]--;
        }

        
        rep(i,n){
            land_dist[i][i] = 0;
        }
        rep(k,n){
            rep(i,n){
                rep(j,n){
                    chmin(land_dist[i][j],land_dist[i][k] + land_dist[k][j]);
                }
            }
        }

        
        rep(i,n){
            sea_dist[i][i] = 0;
        }
        rep(k,n){
            rep(i,n){
                rep(j,n){
                    chmin(sea_dist[i][j],sea_dist[i][k] + sea_dist[k][j]);
                }
            }
        }

        vvll dp(r,vll(n,1LL<<60));
        dp[0][z[0]] = 0;
        rep(i,r-1){
            rep(j,n){
                chmin(dp[i+1][j],dp[i][j] + land_dist[z[i]][z[i+1]]);
                rep(k,n){
                    chmin(dp[i+1][k],dp[i][j] + land_dist[z[i]][j] + sea_dist[j][k] + land_dist[k][z[i+1]]);
                }
            }
        }
        ll ans = 1LL<<60;
        rep(i,n){
            chmin(ans,dp[r-1][i]);
        }
        print(ans);
    }
    
}
accuracy: 1
time_ms: 240
memory_kb: 6192
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define loop(n) for (int tjh = 0; tjh < (int)(n); tjh++)
constexpr int maxN=200;constexpr int maxM=10000;
constexpr ll ma=100'000'000'000LL;
signed main() {
  cin.tie(0)->sync_with_stdio(0);//NOLINT
  cout<<fixed<<setprecision(16);
  int N,M,R,x,y,z0,z1;ll t;char sl;
  array<array<ll,maxN>,maxN>dl,ds;
  array<array<ll,maxN>,2>re0;int p=0,q=1;
  for (;cin>>N>>M,N;) {
    rep(i,N) {
      fill_n(dl[i].begin(),N,ma);fill_n(ds[i].begin(),N,ma);
      dl[i][i]=0;ds[i][i]=0;
    }
    loop(M) {
      cin>>x>>y>>t>>sl;x--;y--;
      if (sl=='L') {
        if (dl[x][y]>t)dl[x][y]=t;
        if (dl[y][x]>t)dl[y][x]=t;
      }else {
        if (ds[x][y]>t)ds[x][y]=t;
        if (ds[y][x]>t)ds[y][x]=t;
      }
    }
    rep(k,N)rep(i,N)rep(j,N) {
      if (dl[i][j]>dl[i][k]+dl[k][j])dl[i][j]=dl[i][k]+dl[k][j];
      if (ds[i][j]>ds[i][k]+ds[k][j])ds[i][j]=ds[i][k]+ds[k][j];
    }
    cin>>R>>z1;z1--;
    fill_n(re0[q].begin(),N,ma);
    re0[q][z1]=0;
    loop(R-1) {
      z0=z1;swap(p,q);cin>>z1;z1--;
      fill_n(re0[q].begin(),N,ma);
      rep(i,N)rep(j,N) {
        t=i==j?re0[p][i]+dl[z0][z1]:re0[p][i]+dl[z0][i]+ds[i][j]+dl[j][z1];
        if (re0[q][j]>t)re0[q][j]=t;
      }
    }
    cout<<*min_element(re0[q].begin(),re0[q].begin()+N)<<'\n';
  }
}
accuracy: 1
time_ms: 170
memory_kb: 4096
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 4e18;

/*-------------------------------------------------------*/
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    for(;;){
        int N,M;
        if(!(cin>>N>>M) || (N==0 && M==0)) break;

        /* 1. 陸路・海路それぞれの隣接行列 */
        vector<vector<ll>> L(N, vector<ll>(N, INF));
        vector<vector<ll>> S(N, vector<ll>(N, INF));
        for(int i=0;i<N;++i) L[i][i]=S[i][i]=0;

        for(int i=0;i<M;++i){
            int x,y,t; char sl;
            cin>>x>>y>>t>>sl; --x;--y;
            if(sl=='L') L[x][y]=L[y][x]=min<ll>(L[x][y],t);
            else        S[x][y]=S[y][x]=min<ll>(S[x][y],t);
        }

        /* 2. Floyd–Warshall (陸路と海路を独立に) */
        for(int k=0;k<N;++k)
            for(int i=0;i<N;++i) if(L[i][k]<INF)
                for(int j=0;j<N;++j) L[i][j]=min(L[i][j],L[i][k]+L[k][j]);
        for(int k=0;k<N;++k)
            for(int i=0;i<N;++i) if(S[i][k]<INF)
                for(int j=0;j<N;++j) S[i][j]=min(S[i][j],S[i][k]+S[k][j]);

        /* 3. 配達順 */
        int R; cin>>R;
        vector<int> Z(R);
        for(int &v:Z){cin>>v;--v;}

        /* 4. DP: dp[b] = 船が b にあり Z[i] を配達し終えた最短時間 */
        vector<ll> dp(N, INF), ndp(N);
        dp[Z[0]] = 0;                    // 初期位置：自分も船も Z[0]

        for(int k=0;k<R-1;++k){
            int cur = Z[k], nxt = Z[k+1];
            fill(ndp.begin(), ndp.end(), INF);

            /* 4-1. 陸路だけで行くケース */
            ll land_only = L[cur][nxt];
            for(int b=0;b<N;++b)
                if(dp[b] < INF && land_only < INF)
                    ndp[b] = dp[b] + land_only;

            /* 4-2. 海路を使うケース（船に一度乗る） */
            /*   pre[b] = dp[b] + L[cur][b]  を一旦作る */
            vector<ll> pre(N, INF);
            for(int b=0;b<N;++b)
                if(dp[b] < INF && L[cur][b] < INF)
                    pre[b] = dp[b] + L[cur][b];

            /*   for each x : min_b { pre[b] + S[b][x] } */
            for(int b=0;b<N;++b) if(pre[b] < INF)
                for(int x=0;x<N;++x) if(S[b][x] < INF)
                    ndp[x] = min(ndp[x], pre[b] + S[b][x] + L[x][nxt]);

            dp.swap(ndp);                // 次のステップへ
        }

        /* 5. 最終ステップの最小値が答え */
        ll ans = *min_element(dp.begin(), dp.end());
        cout << ans << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 4112
final_rank: 4

code_snippet: #include <iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<cstdio>
#include<iomanip>
#include<sstream>
using namespace std;
#define ll long long
#define ft first
#define sd second
#define mst(a,b) memset(a,b,sizeof(a))
typedef pair<int, int> PII;

const int mod =1e9;
const int N = 1e5 + 10;
const int M = 2e4 + 10;
const ll inf = 0x3f3f3f3f3f3f;

int t, l, r,ex, sy,s;
int n,m,cnt=0;
ll ldist[1010][1010], sdist[1010][1010];
ll ord[1010];
ll cost[1010][1010];

void floyd() {
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				ldist[i][j] = min(ldist[i][j], ldist[i][k] + ldist[k][j]);
				sdist[i][j] = min(sdist[i][j], sdist[i][k] + sdist[k][j]);
			}
		}
	}
}

void solve() {
	while (cin >> n >> m) {
		if (n == 0 && m == 0)break;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				ldist[i][j] = sdist[i][j] = inf;
			}
		}
		while (m--) {
			ll x, y, dist;
			char s;
			bool f;
			cin >> x >> y >> dist >> s;
			if (s == 'L')
				ldist[x][y] = ldist[y][x] = min(ldist[x][y], dist);
			else
				sdist[x][y] = sdist[y][x] = min(sdist[x][y], dist);
		}
		int q;
		cin >> q;
		for (int i = 1; i <= q; i++)
			cin >> ord[i];
		for (int i = 0; i <= q; i++) {
			for (int j = 1; j <= n; j++) {
				cost[i][j] = inf;
			}
		}
		floyd();
		for (int i = 1; i <= n; i++)
			ldist[i][i] = sdist[i][i] = 0;
		cost[1][ord[1]] = 0;
		for (int i = 1; i <= q; i++) {
			for (int j = 1; j <= n; j++) {
				cost[i][j] = min(cost[i][j], cost[i - 1][j] + ldist[ord[i - 1]][ord[i]]);
				for (int k = 1; k <= n; k++) {
					cost[i][k] = min(cost[i][k], cost[i - 1][j] + ldist[ord[i - 1]][j] + sdist[j][k] + ldist[k][ord[i]]);
				}
			}
		}
		ll mi = 1e12;
		for (int i = 1; i <= n; i++) {
			mi = min(mi, cost[q][i]);
		}
		cout << mi << endl;
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	t = 1;
	//cin >> t;
	while (t--)
		solve();

	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 17116
final_rank: 19

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
#include <unordered_set>
#include <functional>
using namespace std;
//using namespace atcoder;
using ll = long long;
using P = pair<int, int>;
#define rep(i, n) for (int i = 0; i < (n); i++)
//void chmin(ll & a, ll b) { a = min(a, b); }
//using mint = modint998244353;
//using mint = modint1000000007;

template<class T> inline bool chmin(T & a, T b) { if (a > b) { a = b; return 1; } return 0; }
const ll INF = 1LL << 60;

int main() {
	int N, M;
	while (cin >> N >> M) {
	    if(N==0 && M==0) break;
		vector<vector<ll>> dps(N, vector<ll>(N, INF)),dpl(N,vector<ll>(N,INF));
		for (int v = 0; v < N; v++) dps[v][v] = dpl[v][v] = 0;
		rep(e, M) {
			int x, y;
			ll w;
			char type;
			cin >> x >> y >> w >> type;
			--x, --y; 
			if (type == 'L')chmin(dpl[x][y], w), chmin(dpl[y][x], w);
			else chmin(dps[x][y], w), chmin(dps[y][x], w);
		}
		rep(k, N)rep(i, N)rep(j, N) {
			dpl[i][j] = min(dpl[i][j], dpl[i][k] + dpl[k][j]);
			dps[i][j] = min(dps[i][j], dps[i][k] + dps[k][j]);
		}

		int R;
		cin >> R;
		vector<int> v(R);
		rep(i, R) cin >> v[i], v[i]--;

		vector<vector<ll>> dp(R, vector<ll>(N, INF));
		dp[0][v[0]] = 0;
		rep(i, R - 1) {
			rep(j, N) {
				dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dpl[v[i]][v[i + 1]]);
				rep(k, N) {
					dp[i + 1][k] = min(dp[i + 1][k], dp[i][j] + dpl[v[i]][j] + dps[j][k] + dpl[k][v[i + 1]]);
				}
			}
		}

		ll res = INF;
		rep(i, N) {
			res = min(res, dp[R - 1][i]);
		}
		cout << res << endl;
	}

}
accuracy: 1
time_ms: 220
memory_kb: 5508
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return 0;
    vector<vector<ll>> DL(N,vector<ll>(N,INF/4)), DS(N,vector<ll>(N,INF/4));
    rep(i,0,N) DL[i][i] = DS[i][i] = 0;
    rep(i,0,M) {
        ll U, V, D;
        char C;
        cin >> U >> V >> D >> C;
        U--, V--;
        if (C == 'L') chmin(DL[U][V], D), chmin(DL[V][U], D);
        else chmin(DS[U][V], D), chmin(DS[V][U], D);
    }
    rep(k,0,N) {
        rep(i,0,N) {
            rep(j,0,N) {
                chmin(DL[i][j], DL[i][k] + DL[k][j]);
                chmin(DS[i][j], DS[i][k] + DS[k][j]);
            }
        }
    }
    vector<ll> ANS(N, INF/4);
    int Q;
    int Now = 0;
    cin >> Q >> Now;
    Now--;
    ANS[Now] = 0;
    rep(_,0,Q-1) {
        int Z;
        cin >> Z;
        Z--;
        vector<ll> Next(N, INF/4);
        rep(i,0,N) {
            chmin(Next[i], ANS[i] + DL[Now][Z]);
            rep(j,0,N) {
                chmin(Next[j], ANS[i] + DL[Now][i] + DS[i][j] + DL[j][Z]);
            }
        }
        rep(i,0,N) ANS[i] = Next[i];
        Now = Z;
    }
    ll MIN = INF/4;
    rep(i,0,N) {
        chmin(MIN, ANS[i]);
    }
    cout << MIN << endl;
}
}
accuracy: 1
time_ms: 220
memory_kb: 3824
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define rrep(i,start,end) for (long long i = start;i >= (long long)(end);i--)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define each(p,a) for(auto &p:a)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<long long> vll;
typedef vector<pair<long long ,long long>> vpll;
typedef vector<vector<long long>> vvll;
typedef set<ll> sll;
typedef map<long long , long long> mpll;
typedef pair<long long ,long long> pll;
typedef tuple<long long , long long , long long> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (int)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
inline ll lfloor(ll x,ll m){return (x - ((x % m+ m)%m))/m;}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

// for AOJ or ICPC or etc..
// 全部が0だったらtrueを返す
template<class Tp> bool zero (const Tp &x) {return x == 0;}
template<class Tp, class... Args> bool zero (const Tp &x, const Args& ...args) {return zero(x) and zero(args...);}


/*隣接行列を更新してくDPのイメージ
つながってない辺は重みINF、繋がってたら辺の重みで初期化
O(V^3)
*/
int warshall_floyd(vector<vector<ll>> &dist){
  int size = (int)dist.size();
  rep(k,size){
    rep(i,size){
      rep(j,size){
        if(i == j){
          chmin(dist[i][j],0LL);
        }
        if(dist[i][k] != INF && dist[k][j] != INF){
          chmin(dist[i][j],dist[i][k] + dist[k][j]);
        }
      }
    }
  }
  //負の閉路判定あれば−1大丈夫なら1
  rep(i,size){
    if(dist[i][i]<0){
      return -1;
    }
  }
  return 1;
}

// 変数をちゃんと全部受け取る！
void solve(ll n,ll m){
  vvll ship(n,vll(n,INF)),road(n,vll(n,INF));
  rep(i,m){
    LL(x,y,l);
    Ch(c);
    x--;y--;
    if(c == 'S'){
      chmin(ship[x][y],l);
      chmin(ship[y][x],l);
    }else{
      chmin(road[x][y],l);
      chmin(road[y][x],l);
    }
  }
  warshall_floyd(ship);
  warshall_floyd(road);
  LL(r);
  vll z(r);cin >> z;z--;
  vvll dp(r,vll(n,INF));
  dp[0][z[0]] = 0;
  rep(i,r-1){
    ll now = z[i];
    ll to = z[i+1];
    rep(j,n){
      if(dp[i][j] == INF)continue;
      chmin(dp[i+1][j],dp[i][j] + road[now][to]);//船を置いたまま陸路で移動
      rep(k,n){
        if(j == k or ship[j][k] == INF){
          continue;
        }
        //now-> j -> k -> to
        ll cost = road[now][j] + ship[j][k] + road[k][to];
        chmin(dp[i+1][k],dp[i][j] + cost);
      }
    }
  }
  ll ans = INF;
  rep(i,n){
    chmin(ans,dp[r-1][i]);
  }
  cout << ans << endl;

}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n,m);//変数数調整
    if(zero(n,m))break;
    solve(n,m);
  }
}
accuracy: 1
time_ms: 260
memory_kb: 5396
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;
const int MAX_V = 200, INF = 200000;
int dl[MAX_V][MAX_V], ds[MAX_V][MAX_V];
int V;
void warshall_floyd(int d[MAX_V][MAX_V]);

const int MAX_R = 1000;
int N, M, R, xi, yi, ti;
char sli;
int z[MAX_R], ans[2][MAX_V];

int main() {
    while (cin >> N >> M) {
        if (N == 0 && M == 0)
            break;
        V = N;
        for (int i = 0; i < V; i++) {
            for (int j = 0; j < V; j++) {
                dl[i][j] = INF;
                ds[i][j] = INF;
            }
        }
        for (int i = 0; i < V; i++) {
            dl[i][i] = 0;
            ds[i][i] = 0;
        }
        for (int i = 0; i < M; i++) {
            cin >> xi >> yi >> ti >> sli;
            xi--; yi--;
            if (sli == 'L') {
                dl[xi][yi] = min(dl[xi][yi], ti);
                dl[yi][xi] = min(dl[yi][xi], ti);
            }
            if (sli == 'S') {
                ds[xi][yi] = min(ds[xi][yi], ti);
                ds[yi][xi] = min(ds[yi][xi], ti);
            }
        }
        cin >> R;
        for (int i = 0; i < R; i++) {
            cin >> z[i];
            z[i]--;
        }
        warshall_floyd(dl);
        warshall_floyd(ds);
        for (int i = 0; i < N; i++)
            ans[0][i] = (int)1e9;
        ans[0][z[0]] = 0;
        for (int i = 1; i < R; i++) {
            for (int j = 0; j < N; j++)
                ans[i & 1][j] = (int)1e9;
            for (int j = 0; j < N; j++) {
                for (int k = 0; k < N; k++) {
                    ans[i & 1][k] = min(ans[i & 1][k], ans[(i - 1) & 1][j] + dl[z[i - 1]][j] + ds[j][k] + dl[k][z[i]]);
                    if (j == k)
                        ans[i & 1][k] = min(ans[i & 1][k], ans[(i - 1) & 1][j] + dl[z[i - 1]][z[i]]);
                }
            }
        }
        int tmp = INF;
        for (int i = 0; i < N; i++)
            tmp = min(tmp, ans[(R - 1) & 1][i]);
        cout << tmp << endl;
    }
    return 0;
}

void warshall_floyd(int d[MAX_V][MAX_V]) {
    for (int k = 0; k < V; k++) {
        for (int i = 0; i < V; i++) {
            for (int j = 0; j < V; j++)
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        }
    }
}
accuracy: 1
time_ms: 180
memory_kb: 3688
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define inr(l, x, r) (l <= x && x < r)
#define ll long long
#define ld long double
#define pii pair<ll,ll>

constexpr ll IINF = 1001001001;
constexpr ll INF = 9e18;

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}


int main(){
    while(1){
        ll n, m;cin >> n >> m;
        if(n+m == 0) return 0;
        vector<vector<pii>> gl(n),gs(n);
        vector<vector<ll>> ldist(n,vector<ll>(n,1LL<<60)), sdist(n,vector<ll>(n,1LL<<60));
        rep(i, 0, n) ldist[i][i] = 0, sdist[i][i] = 0;
        rep(i, 0, m){
            ll s, t, d; cin >> s >> t >> d;
            s--;t--;
            char type; cin >> type;
            if(type == 'L'){
                gl[s].push_back({t, d});
                gl[t].push_back({s, d});
                chmin(ldist[s][t], d);
                chmin(ldist[t][s], d);
            }else{
                gs[s].push_back({t, d});
                gs[t].push_back({s, d});
                chmin(sdist[s][t], d);
                chmin(sdist[t][s], d);
            }
        }
        rep(k, 0, n)rep(i, 0, n)rep(j, 0, n){
            chmin(ldist[i][j],ldist[i][k]+ldist[k][j]);
            chmin(sdist[i][j],sdist[i][k]+sdist[k][j]);
        }
        ll r; cin >> r;
        vector<ll> tour(r);
        rep(i, 0, r){
            cin >> tour[i];
            tour[i]--;
        }
        vector<vector<ll>> dp(r+1, vector<ll>(n,(1LL<<60)));
        dp[0][tour[0]] = 0;
        rep(i, 0, r-1){
            rep(j, 0, n){
                chmin(dp[i+1][j], dp[i][j]+ldist[tour[i]][tour[i+1]]);
                rep(k, 0, n){
                    chmin(dp[i+1][k], dp[i][j]+ldist[tour[i]][j]+sdist[j][k]+ldist[k][tour[i+1]]);
                }
            }
        }
        ll ans = (1LL<<60);
        rep(i, 0, n) chmin(ans, dp[r-1][i]);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 5644
final_rank: 15

code_snippet: #include <bits/stdc++.h>

int solve() {
    int n, m;
    std::cin >> n >> m;
    if (n == 0) return 1;
    const int INF = 1e9;
    std::vector L(n, std::vector<int>(n, INF));
    std::vector S(n, std::vector<int>(n, INF));
    for (int i = 0; i < m; i++) {
        int u, v, t;
        char c;
        std::cin >> u >> v >> t >> c;
        u--; v--;
        if (c == 'L') {
            L[u][v] = std::min(L[u][v], t);
            L[v][u] = std::min(L[v][u], t);
        } else {
            S[u][v] = std::min(S[u][v], t);
            S[v][u] = std::min(S[v][u], t);
        }
    }
    for (int i = 0; i < n; i++) L[i][i] = S[i][i] = 0;
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                L[i][j] = std::min(L[i][j], L[i][k] + L[k][j]);
                S[i][j] = std::min(S[i][j], S[i][k] + S[k][j]);
            }
        }
    }
    int q;
    std::cin >> q;
    std::vector<int> z(q);
    for (int i = 0; i < q; i++) std::cin >> z[i], z[i]--;
    std::vector<int> dist(n, INF);
    dist[z[0]] = 0;
    for (int i = 0; i + 1 < q; i++) {
        std::vector<int> ndist(n, INF);
        // 今船がある場所
        for (int j = 0; j < n; j++) {
            if (dist[j] == INF) continue;
            // 次船がある場所
            for (int k = 0; k < n; k++) {
                if (j == k) {
                    if (L[z[i]][z[i + 1]] != INF) {
                        ndist[k] = std::min(ndist[k], dist[j] + L[z[i]][z[i + 1]]);
                    }
                } else {
                    if (L[z[i]][j] != INF && S[j][k] != INF && L[k][z[i + 1]] != INF) {
                        ndist[k] = std::min(ndist[k], dist[j] + L[z[i]][j] + S[j][k] + L[k][z[i + 1]]);
                    }
                }
            }
        }
        dist = std::move(ndist);
    }
    std::cout << *std::min_element(dist.begin(), dist.end()) << '\n';
    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 330
memory_kb: 3716
final_rank: 9

code_snippet: // 18:10
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll LINF = 1001001001001001001ll;

struct Warshall_Floyd{
    vector<vector<ll>> dist;
    int size;

    Warshall_Floyd(int N) : size(N), dist(N, vector<ll>(N, LINF)){
        for(int i = 0; i < N; i++) dist[i][i] = 0;
    }
    void add_edge(int u, int v, int w){
        dist[u][v] = w;
    }
    bool solve(){
        for(int k = 0; k < size; k++){
            for(int i = 0; i < size; i++){
                for(int j = 0; j < size; j++){
                    if(dist[i][k] == LINF || dist[k][j] == LINF) continue;
                    if(dist[i][j] > dist[i][k] + dist[k][j]){
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                }
            }
        }
        for(int i = 0; i < size; i++){
            if(dist[i][i] < 0) return false;
        }
        return true;
    }
};

int main(){
    while(1){
        int N, M; cin >> N >> M;
        if(N == 0) break;
        Warshall_Floyd land(N), sea(N);
        for(int i = 0; i < M; i++){
            int x, y, t;
            char sl;
            cin >> x >> y >> t >> sl;
            x--, y--;
            if(sl == 'L'){
                land.add_edge(x, y, t);
                land.add_edge(y, x, t);
            }
            else{
                sea.add_edge(x, y, t);
                sea.add_edge(y, x, t);
            }
        }
        land.solve();
        sea.solve();

        vector<ll> dp1(N, LINF), dp2(N, LINF), nxt(N, LINF);
        int R; cin >> R;
        int start; cin >> start;
        start--;
        dp1[start] = 0;

        for(int _ = 1; _ < R; _++){
            int goal; cin >> goal;
            goal--;
            vector<ll> dp2(N, LINF), nxt(N, LINF);

            // only land
            for(int i = 0; i < N; i++){
                nxt[i] = min(nxt[i], dp1[i] + land.dist[start][goal]);
            }
            // land -> boat
            for(int i = 0; i < N; i++){
                dp2[i] = min(dp2[i], dp1[i] + land.dist[start][i]);
            }
            // dp2 -> nxt
            for(int i = 0; i < N; i++){
                // boat -> sea
                nxt[goal] = min(nxt[goal], dp2[i] + sea.dist[i][goal]);
                // boat -> sea -> land
                for(int j = 0; j < N; j++){
                    nxt[j] = min(nxt[j], dp2[i] + sea.dist[i][j] + land.dist[j][goal]);
                }
            }

            swap(dp1, nxt);
            // for(int i = 0; i < N; i++) cout << dp1[i] << " ";
            // cout << endl;
            start = goal;
        }

        ll ans = LINF;
        for(int i = 0; i < N; i++) ans = min(ans, dp1[i]);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3780
final_rank: 6

code_snippet: #include <algorithm>
#include <cctype>
#include <climits>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

const int INF = INT_MAX;

//Graph
struct edge{int to, cost;};
class Graph{
private:
  vector<vector<edge>>neighbors;
  vector<ll>shortest;
  vector<int>prev;
  //this is for warshall froid.
  vector<vector<ll>>distances;
  int V;
  int E;

public:
  Graph(const int n){
    V = n;
    neighbors = vector<vector<edge>>(V);
    shortest = vector<ll>(V, LLONG_MAX);
    prev = vector<int>(V, -1);
    distances = vector<vector<ll>>(V, vector<ll>(V, LLONG_MAX));
  };

  void add_edge(const int f, const int t, const int c=INT_MAX){
    edge e; e.to = t; e.cost = c;
    neighbors[f].push_back(e);
    E++;
  }

  //Dijkstra
  typedef pair<ll, int> P;
  void dijkstra(const int s){
    fill(shortest.begin(), shortest.end(), LLONG_MAX);
    fill(prev.begin(), prev.end(), -1);
    priority_queue<P, vector<P>, greater<P>>pque;
    shortest[s] = 0;
    pque.push(P(0, s));

    while(!pque.empty()){
      P p = pque.top(); pque.pop();
      if(shortest[p.second] < p.first)continue;
      for(int i = 0; i < neighbors[p.second].size(); i++){
        edge e = neighbors[p.second][i];
        if(shortest[e.to] > shortest[p.second] + e.cost){
          shortest[e.to] = shortest[p.second] + e.cost;
          prev[e.to] = p.second;
          pque.push(P(shortest[e.to], e.to));
        }
      }
    } 
  }

  //Bellman-Ford algorithm
  void Bellman_Ford(const int s){
    fill(shortest.begin(), shortest.end(), LLONG_MAX);
    fill(prev.begin(), prev.end(), -1);
    shortest[s] = 0;
    while(true){
      bool updated = false;
      for(int i = 0; i < V; i++){
        for(int j = 0; j < neighbors[i].size(); j++){
          edge e = neighbors[i][j];
          if(shortest[i] != LLONG_MAX && shortest[i] + e.cost < shortest[e.to]){
            shortest[e.to] = shortest[i] + e.cost;
            prev[e.to] = i;
            updated = true;
          }
        }
      }

      if(!updated)break;
    }
  }

  //Warshall_froid
  void warshall_froid(){
    distances = vector<vector<ll>>(V, vector<ll>(V, LLONG_MAX));
    for(int i = 0; i < V; i++){
      distances[i][i] = 0;
      for(int j = 0; j < neighbors[i].size(); j++){
        edge e = neighbors[i][j];
        distances[i][e.to] = e.cost;
      }
    }

    for(int k = 0; k < V; k++){
      for(int i = 0; i < V; i++){{
        for(int j = 0; j < V; j++){
          if(distances[i][k] != LLONG_MAX && distances[k][j] != LLONG_MAX) distances[i][j] = min(distances[i][j], distances[i][k] + distances[k][j]);
        }
      }
      }
    }
  }

  //find negative loop
  bool find_negative_loop(){
    fill(shortest.begin(), shortest.end(), 0);
    for(int i = 0; i < V; i++){
      for(int j = 0; j < V; j++){
        for(int k = 0; k < neighbors[j].size(); k++){
          edge e = neighbors[j][k];
          if(shortest[j] + e.cost < shortest[e.to]){
            shortest[e.to] = shortest[j] + e.cost;
            if(i = V-1)return true;
          }
        }
      }
    }
    return false;
  }

  //get the shortest path from s to g
  //make sure it is done after algorithm
  ll get_value(const int g){
    return shortest[g];
  }
  ll get_value(const int s, const int g){
    return distances[s][g];
  }


  //get the shortest path route from s to g
  //make sure it is done after algorithm
  vector<int> get_route(const int s, const int g){
    vector<int>routes;
    if(get_value(g) == LLONG_MAX)return routes;

    for(int t = g; prev[t] != -1; t = prev[t])routes.push_back(t);
    routes.push_back(s);
    reverse(routes.begin(), routes.end());
    return routes;
  }
};


int main(){
  while(true){
    int N, M; scanf("%d%d", &N, &M);
    if(N == 0 && M == 0)break;
    Graph L(N);
    Graph S(N);

    for(int m = 0; m < M; m++){
      int x, y, t; char c; scanf("%d%d%d %c", &x, &y, &t, &c);

      if(c == 'L'){
        L.add_edge(x-1, y-1, t);
        L.add_edge(y-1, x-1, t);
      }
      else{
        S.add_edge(x-1, y-1, t);
        S.add_edge(y-1, x-1, t);
      }
    }
    
    L.warshall_froid();
    S.warshall_froid();

    int R; scanf("%d", &R);
    vector<vector<ll>>dp(R, vector<ll>(N, LLONG_MAX));
    vector<int>order(R);
    for(int r = 0; r < R; r++){
      scanf("%d", &order[r]);
    }

    dp[0][order[0]-1] = 0;
    for(int i = 1; i < R; i++){
      for(int j = 0; j < N; j++){
        for(int k = 0; k < N; k++){
          if(j == k){
            if(dp[i-1][j] != LLONG_MAX && L.get_value(order[i-1]-1, order[i]-1) != LLONG_MAX)dp[i][j] = min(dp[i][j], dp[i-1][j]+L.get_value(order[i-1]-1, order[i]-1));
          }
          else{
            if(L.get_value(order[i-1]-1, k) != LLONG_MAX && dp[i-1][k] != LLONG_MAX && S.get_value(k, j) != LLONG_MAX && L.get_value(j, order[i]-1) != LLONG_MAX) dp[i][j] = min(dp[i][j], L.get_value(order[i-1]-1, k) + dp[i-1][k] + S.get_value(k, j) + L.get_value(j, order[i]-1));
          }
        }
      }
    }

    ll minimum = LLONG_MAX;
    for(int i = 0; i < N; i++){
      minimum = min(minimum, dp[R-1][i]);
    }

    printf("%lld\n", minimum);
  }

}
accuracy: 1
time_ms: 460
memory_kb: 5668
final_rank: 18

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int N, int M) {
    const int INF = 1e9;
    vector A(N, vector(N, INF)), B(N, vector(N, INF));
    for(int i : rep(M)) {
        int x = in(), y = in(), t = in(); char s = in(); x--, y--;
        if(s == 'L') {
            chmin(A[x][y], t);
            chmin(A[y][x], t);
        } else {
            chmin(B[x][y], t);
            chmin(B[y][x], t);
        }
    }

    for(int i : rep(N)) A[i][i] = 0;
    for(int i : rep(N)) B[i][i] = 0;
    for(int k : rep(N)) for(int i : rep(N)) for(int j : rep(N)) chmin(A[i][j], A[i][k] + A[k][j]);
    for(int k : rep(N)) for(int i : rep(N)) for(int j : rep(N)) chmin(B[i][j], B[i][k] + B[k][j]);

    int R = in();
    vector<int> z = in(R);
    for(int& i : z) i--;

    vector dp(N, INF);
    dp[z[0]] = 0;
    for(int i : rep(1, R)) {
        vector nt(N, INF);
        for(int v : rep(N)) if(dp[v] < INF) {
            if(A[z[i - 1]][z[i]] < INF)
                chmin(nt[v], dp[v] + A[z[i - 1]][z[i]]);
            if(A[z[i - 1]][v] < INF and B[v][z[i]] < INF)
                chmin(nt[z[i]], dp[v] + A[z[i - 1]][v] + B[v][z[i]]);
            for(int x : rep(N)) {
                if(A[z[i - 1]][v] < INF and B[v][x] < INF and A[x][z[i]] < INF)
                    chmin(nt[x], dp[v] + A[z[i - 1]][v] + B[v][x] + A[x][z[i]]);
            }
        }
        dp = move(nt);
    }
    return min_of<int>(dp).val;
}

int main() {
    while(true) {
        int N = in(), M = in();
        if(make_pair(N, M) == make_pair(0, 0)) return 0;
        print(solve(N, M));
    }
}
accuracy: 1
time_ms: 280
memory_kb: 3508
final_rank: 3