/*
* File: pku1158.cpp
* Author: chenjiang
*好长的代码啊,4012B,最短路径的应用,主要是边长是动态变化的,比较难处理。
* Created on 2010年4月22日, 下午3:37
*/
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
#define _max 305
#define inf 2147480
int n, m, dist[_max], mapmap[_max][_max];
bool visited[_max];
int source, sink;
struct node {
char ci; //当前颜色
int ric; //初始颜色能维持的时间
int tib; //蓝色能维持的时间
int tip; //紫色能维持的时间
} a[_max];
int MIN(int a, int b) {
if (a <= b)return a;
else return b;
}
void change(char &c, int &t, int v, int time) {
int i, j, k, num;
if (time < a[v].ric)//总时间小于v开始颜色的剩余时间
{
c = a[v].ci;
t = a[v].ric - time;
} else {
if (a[v].tib + a[v].tip != 0)num = (time - a[v].ric) % (a[v].tib + a[v].tip);
else num = 0;
if (a[v].ci == 'B')//初始颜色为蓝色
{
if (num < a[v].tip)//当前颜色为紫色
{
c = 'P';
t = a[v].tip - num;
} else//当前颜色为蓝色
{
c = 'B';
t = a[v].tip + a[v].tib - num;
}
} else {
if (num < a[v].tib) {
c = 'B';
t = a[v].tib - num;
} else {
c = 'P';
t = a[v].tib + a[v].tip - num;
}
}
}
}
int dist_time(int v, int u, int time) {
int vt, ut;
char vc, uc;
change(vc, vt, v, time); //找出总时间是time时当前颜色和这种颜色能持续的时间
change(uc, ut, u, time);
if (vc == uc)return mapmap[v][u];
if (vc == 'B')//v的颜色为 B
{
if (vt != ut)return mapmap[v][u] + MIN(vt, ut); //等待v变色或者u变色,取vt和ut中较小的
else//vt==ut,v,u同时变色
{
if (a[v].tip == a[u].tib) {
if (a[v].tib == a[u].tip)
return inf;
else {
return mapmap[v][u] + vt + a[v].tip + MIN(a[v].tib, a[u].tip);
}
}
//a[v].tip!=a[u].tib
return mapmap[v][u] + vt + MIN(a[v].tip, a[u].tib);
}
} else {
if (vt != ut)return mapmap[v][u] + MIN(vt, ut);
else {
if (a[v].tib == a[u].tip) {
if (a[v].tip == a[u].tib)
return inf;
else
return mapmap[v][u] + vt + a[v].tib + MIN(a[v].tip, a[u].tib);
} else
return mapmap[v][u] + vt + MIN(a[v].tib, a[u].tip);
}
}
}
int DJ() {
int i, j, k;
memset(visited, 0, sizeof (visited));
for (i = 1; i <= n; i++) {
if (i != source)dist[i] = dist_time(source, i, 0);
}
dist[source] = 0;
visited[source] = 1;
for (i = 1; i <= n; i++) {
k = 0;
dist[k] = inf;
for (j = 1; j <= n; j++) {
if (!visited[j] && dist[j] < dist[k])k = j;
}
visited[k] = 1;
for (j = 1; j <= n; j++) {
if (!visited[j]) {
int temp = dist_time(k, j, dist[k]);
if (temp + dist[k] < dist[j]) {
dist[j] = temp + dist[k];
}
}
}
}
return dist[sink];
}
/*
*
*/
int main(int argc, char** argv) {
int i, j;
char ch;
//freopen("a.a", "r", stdin);
while (cin >> source >> sink) {
cin >> n >> m;
for (i = 1; i <= n; i++) {
mapmap[i][i] = 0;
for (j = 1; j <= n; j++) {
mapmap[i][j] = inf;
}
}
for (i = 1; i <= n; i++) {
cin >> a[i].ci >> a[i].ric >> a[i].tib >> a[i].tip;
}
for (i = 1; i <= m; i++) {
int s, e, len;
cin >> s >> e >> len;
mapmap[s][e] = mapmap[e][s] = len;
}
int ans = DJ();
if (ans < inf)cout << ans << endl;
else cout << "0" << endl;
}
return (EXIT_SUCCESS);
}