#include #include #include #include #include using namespace std; int getidx(char c) { if(c >= 'A' && c <= 'Z') return c - 'A'; return c - 'a' + 26; } const int INF = 1.01e9; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, dest, edgeCnt; cin >> n >> dest >> edgeCnt; vector> edges(n); // edges[i][char] -> j if exists for(auto& x: edges) { x.assign(52, -1); } vector isdest(n); while(dest--) { int x; cin >> x; isdest[--x] = true; } for(int i = 0; i < edgeCnt; i++) { int a; char c; int b; cin >> a >> c >> b; a--; b--; edges[a][getidx(c)] = b; } vector> epsilondp(n); for(auto& x: epsilondp) x.assign(n, INF); for(int i = 0; i < n; i++) { for(int a = 26; a < 52; a++) { if(edges[i][a] >= 0) epsilondp[i][edges[i][a]] = 1; } } for(int k = 0; k < n; k++) for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) epsilondp[i][j] = min(epsilondp[i][j], epsilondp[i][k] + epsilondp[k][j]); vector>> dp(n); for(auto& x: dp) { x.resize(n); for(auto& y: x) { y.assign(2, INF); } } dp[0][0][0] = 0; priority_queue, vector>, greater>> q; q.push({0, 0, 0, 0}); while(q.size()) { auto [dist, s1, s2, diff] = q.top(); q.pop(); cerr << s1 << " " << s2 << " " << diff << ": " << dist << endl; if(diff && isdest[s1] && isdest[s2]) { cout << dist << "\n"; return 0; } if(dp[s1][s2][diff] != dist) continue; for(int x = 0; x < 52; x++) { if(edges[s1][x] < 0 || edges[s2][x] < 0) continue; int ns1 = edges[s1][x]; int ns2 = edges[s2][x]; if(dp[ns1][ns2][diff] > 2 + dist) { dp[ns1][ns2][diff] = 2 + dist; q.push({dp[ns1][ns2][diff], ns1, ns2, diff}); } } if(diff == 0) { // you can e-transition to something and then consume assert(s1 == s2); for(int a = 26; a < 52; a++) { if(edges[s1][a] < 0) continue; for(int b = 26; b < a; b++) { if(edges[s2][b] < 0) continue; int ns1 = edges[s1][a]; int ns2 = edges[s2][b]; if(dp[ns1][ns2][1] > dist + 2) { dp[ns1][ns2][1] = dist + 2; q.push({dp[ns1][ns2][1], ns1, ns2, 1}); } } } for(int i = 0; i < n; i++) { if(epsilondp[s1][i] == INF) continue; if(isdest[s1] && isdest[i]) { if(dp[s1][i][1] > dist + epsilondp[s1][i]) { dp[s1][i][1] = dist + epsilondp[s1][i]; q.push({dp[s1][i][1], s1, i, 1}); } } for(int a = 0; a < 26; a++) { if(edges[s1][a] < 0 || edges[i][a] < 0) continue; int ns1 = edges[s1][a]; int ns2 = edges[i][a]; if(dp[ns1][ns2][1] > dist + epsilondp[s1][i] + 2) { dp[ns1][ns2][1] = dist + epsilondp[s1][i] + 2; q.push({dp[ns1][ns2][1], ns1, ns2, 1}); } } } } else { // you can e-transition arbitrarily by one for(int a = 26; a < 52; a++) { if(edges[s1][a] >= 0) { int ns1 = edges[s1][a]; int ns2 = s2; if(dp[ns1][ns2][1] > dist + 1) { dp[ns1][ns2][1] = dist + 1; q.push({dp[ns1][ns2][1], ns1, ns2, 1}); } } if(edges[s2][a] >= 0) { int ns1 = s1; int ns2 = edges[s2][a]; if(dp[ns1][ns2][1] > dist + 1) { dp[ns1][ns2][1] = dist + 1; q.push({dp[ns1][ns2][1], ns1, ns2, 1}); } } } } } cout << "-1\n"; }