#include using namespace std; using ll=long long; using ld=double; using vll=vector; using vvll=vector>; #define FOR(i,a,b) for(ll i=a;i<(ll)b;++i) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define aa first #define bb second #define PB push_back #define EQ(a,b) (fabs(a-b)<=(fabs(a+b)*EPS)) #define MOD ((ll)(1e9+7)) #define dbg cerr #define out(n) cout << n << '\n' #define INF (1ll << 50) //#define dbg if(0)cerr struct Dijkstra { struct Edge{ ll v,w; // destination and weight bool operator<(const Edge& a)const{return w>a.w;} }; ll n; vector> g; vll d,p; Dijkstra(ll n): n(n), g(vector>(n)), d(vll(n)), p(vll(n)) {} void add_edge(ll u,ll v,ll w){ //dbg << "add edge: " << u << ' ' << v << ' ' << w << endl; g[u].PB({v,w}); } void run(ll s){ F(n)d[i]=INF,p[i]=-1; d[s]=0; priority_queue q; q.push({s,d[s]}); while(q.size()){ auto u=q.top().v;q.pop(); for(auto e:g[u]) if(d[e.v]>d[u]+e.w) { d[e.v]=d[u]+e.w,p[e.v]=u,q.push({e.v,d[e.v]}); assert(1e14); } } } }; void print(vector> & g, ll n) { F(n){ FF(n){ dbg << g[i][j]; } dbg << '\n'; } dbg << endl; } int main(){ dbg << "BRUTE :O" << endl; ios::sync_with_stdio(0);cin.tie(0); ll n,m,q,c[3]; c[0]=0; cin>>n>>m>>q>>c[1]>>c[2]; Dijkstra dj(n+q); vector> g(n+q+100); F(m){ ll u,v; char t; cin>>u>>v>>t; t = (t == 'O' ? 1 : 2); dj.add_edge(u,v,c[t]); dj.add_edge(v,u,c[t]); g[u][v] = t; g[v][u] = t; } //print(g, n); set skipped; F(q){ ll a,b; cin>>a>>b; map ne; if (skipped.count(a) || skipped.count(b) || g[a].count(b) && g[a][b] != 0) { skipped.insert(n+i); skipped.insert(i+n); } else { for (auto j: g[a]) { ne[j.aa] = (j.bb + 2*g[b][j.aa])%3; } for (auto j: g[b]) { ne[j.aa] = (2*j.bb + g[a][j.aa])%3; } for (auto j: ne) { if (j.bb==0)continue; dj.add_edge(i+n,j.aa,c[j.bb]); dj.add_edge(j.aa,i+n,c[j.bb]); g[j.aa][n+i] = j.bb; g[n+i][j.aa] = j.bb; } } dj.run(0); ll res=0; FF(n+i+1) { assert(dj.d[j] <= INF); if (dj.d[j] < INF) res+=dj.d[j]; } out(res); //print(g, n + i + 1); } return 0; }