// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

#include<iostream>

#include<queue>

#include<cmath>



using namespace std;



typedef long long ll;



const int maxn = 1005;

const int maxl = 105;

const ll inf = 1ll<<55;

const double eps = 1e-8;



struct edge

{

	int to,val,mag;

	edge(int a,int b,int c):to(a),val(b),mag(c){}

};



struct node

{

	int to,mag;

	ll len;

	node(int a,int b,ll c):to(a),mag(b),len(c){}

	bool operator<(const node& a)const

	{

		return len > a.len;

	}

};



struct point

{

	double xi,lef,di;

	point(){}

	point(double a,double b,double c):xi(a),lef(b),di(c){}

};



vector<edge> v[maxn];

bool vis[maxn][maxl];

ll dis[maxn][maxl];



int n,s1,s2,tt,sp;

struct line

{

	point s[maxl];int top;

	void build()

	{

		top = 0;

		for(int i=sp;i>=0;i--)

		{

			if(dis[tt][i]==inf)

				continue;

			while(top&&i*s[top-1].lef+dis[tt][i]<=eps+s[top-1].xi*s[top-1].lef+s[top-1].di)

				top--;

			s[top] = point(i,top?(dis[tt][i]-s[top-1].di)/(s[top-1].xi-i):0,dis[tt][i]);

			top++;

		}

	}

}p1,p2;



int f1,f2;



double f(double x)

{

	return fabs(p1.s[f1].xi*x+p1.s[f1].di-p2.s[f2].xi*x-p2.s[f2].di);

}

double cal(double pl,double pr)

{

	if(abs((p2.s[f2].xi-p1.s[f1].xi))<=eps)

		return   fabs(p1.s[f1].di-p2.s[f2].di);

	pl = ceil(pl);pr = floor(pr);

	double jiao = (p1.s[f1].di-p2.s[f2].di)/(p2.s[f2].xi-p1.s[f1].xi);

	if(jiao>pr+eps)

		return f(pr);

	if(jiao<pl-eps)

		return f(pl);

	return min(f(ceil(jiao)),f(floor(jiao)));

}

double sol()

{

	double res = inf;

	vector<double> bl,v1,v2;

	for(int i=0;i<p1.top;i++)

	{

		v1.push_back(p1.s[i].lef);

		bl.push_back(p1.s[i].lef);

	}

	for(int i=0;i<p2.top;i++)

	{

		v2.push_back(p2.s[i].lef);

		bl.push_back(p2.s[i].lef);

	}

	sort(bl.begin(),bl.end());bl.push_back(1ll<<42);

	for(int i=2;i<bl.size();i++)

	{

		double va = bl[i];

		f1 = lower_bound(v1.begin(),v1.end(),va-eps)-v1.begin()-1;

		f2 = lower_bound(v2.begin(),v2.end(),va-eps)-v2.begin()-1;

		res = min(cal(bl[i-1],va),res);

	}

	return res;

}

void dij(int s)

{

	priority_queue<node> q;

	memset(vis,0,sizeof(vis));

	for(int i=1;i<=n;i++)

		fill(dis[i],dis[i]+sp+1,inf);

	dis[s][0] = 0;q.push(node(s,0,0));

	while(!q.empty())

	{

		node t = q.top();q.pop();

		if(vis[t.to][t.mag])

			continue;

		vis[t.to][t.mag] = 1;

		for(int i=0;i<v[t.to].size();i++)

		{

			int toit = v[t.to][i].to;

			if(dis[toit][t.mag+v[t.to][i].mag]>dis[t.to][t.mag]+v[t.to][i].val)

			{

				dis[toit][t.mag+v[t.to][i].mag]=dis[t.to][t.mag]+v[t.to][i].val;

				q.push(node(toit,t.mag+v[t.to][i].mag,dis[toit][t.mag+v[t.to][i].mag]));

			}

		}

	}

}

int main()

{

	int m,a,b;char s[20];

	while(scanf("%d%d%d%d%d",&n,&m,&s1,&s2,&tt)&&n)

	{

		sp = 0;

		for(int i=1;i<=n;i++)

			v[i].clear();

		for(int i=0;i<m;i++)

		{

			scanf("%d%d%s",&a,&b,s);

			if(s[0]=='x')

			{

				sp++;

				v[a].push_back(edge(b,0,1));

				v[b].push_back(edge(a,0,1));

			}

			else

			{

				int val = atoi(s);

				v[a].push_back(edge(b,val,0));

				v[b].push_back(edge(a,val,0));

			}

		}

		dij(s1);p1.build();

		dij(s2);p2.build();

		printf("%.0f\n",sol());

	}

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<iostream>

#define ll long long

#define abs(x) (x > 0 ? x : -(x))

#define F(a,b,c) ((a) + (b) * (c))

using namespace std;



const int maxn = 1200;

const int maxm = 2200;

const ll inf1 = 1000000000ll * 1100;

const ll inf = (1ll<<60);

int n,m,S1,S2,T,tot;

char ss[110];

int get(char *ss)

{

    int ret = 0;

    for (int i = 0; ss[i]; i++) {

        ret = ret * 10 + ss[i] - '0';

    }

    return ret;

}

ll a[2][110],b[2][110],f[2][110];

struct EE

{

    int to,ne;

    ll w;

    bool f;

}e[maxm * 2];

int L,head[maxn];

void adde(int u,int v,ll w)

{

    e[L].to = v;

    e[L].w = w;

    e[L].f = false;

    if (w == -1) e[L].f = true;

    e[L].ne = head[u];

    head[u] = L++;

}

bool vis[maxn][maxn];

ll dis[2][maxn][maxn];

int que[maxn * maxn][2];

void spfa(int s,int t,int tt)

{

    for (int i = 0; i < n; i++)

        for (int j = 0; j <= tot; j++) {

            dis[tt][i][j] = inf;

            vis[i][j] = false;

        }

    vis[s][0] = true;

    dis[tt][s][0] = 0;

    int fron,rear;

    fron = rear = 0;

    que[rear][0] = s;

    que[rear][1] = 0;

    rear++;

    while (fron != rear) {

        int u1,u2;

        u1 = que[fron][0];

        u2 = que[fron][1];

        vis[u1][u2] = false;

        fron++;

      //  cout<<fron<<' '<<rear<<' '<<u1<<' '<<u2<<endl;

        if (fron == maxn * maxn) fron = 0;

        for (int i = head[u1]; i != -1; i = e[i].ne) {

            int p = e[i].f,v = e[i].to;

            ll w;

            if (u2 + p > tot) continue;

            if (p == 1) w = 0;

            else w = e[i].w;

            if (dis[tt][v][u2 + p] > dis[tt][u1][u2] + w) {

                dis[tt][v][u2 + p] = dis[tt][u1][u2] + w;

                if (!vis[v][u2 + p]) {

                    vis[v][u2 + p] = true;

                    que[rear][0] = v;

                    que[rear][1] = u2 + p;

                    rear++;

                    if (rear == maxn * maxn) rear = 0;

                }

            }

        }

    }

}

int cal(int s,int t,ll x,int tt)

{

    for (int i = 0; i < L; i++)

    if (e[i].f)

        e[i].w = x;

    //spfa(s,t);

    ll w = inf;

    int ret;

    for (int i = 0; i <= tot; i++)

        if (dis[tt][t][i] + i * x <= w) {

            w = dis[tt][t][i] + i * x;

            ret = i;

        }

    return ret;

}

void get(int s,int t,ll *f,ll *a,ll *b,int tt)

{

    ll R = inf1;

    ll now = -1;

    int m = 0;

    while (R >= 0) {

        ll l = 0,r = R;

        while (l < r) {

            ll mid = (l + r + 1) / 2;

            if (cal(s,t,mid,tt) == now)

                r = mid - 1;

            else

                l = mid;

          //  cout<<l<<endl;

        }

       // cout<<l<<endl;

        ll x = cal(s,t,l,tt);

        if (x == now) {

            f[m++] = -1;

            R = -1;

        }

        else {

            now = x;

            a[m] = dis[tt][T][now];

            b[m] = now;

            f[m++] = l;

            R = l;

        }

    }

}

ll cal2(ll a0,ll b0,ll a1,ll b1,ll tmax,ll tmin)

{

    ll l,r;

    l = tmin,r = tmax;

    while (l + 10 < r) {

        ll mid1 = l + (r - l) / 3;

        ll mid2 = l + (r - l) * 2 / 3;

        if (abs(F(a0,b0,mid1) - F(a1,b1,mid1)) > abs(F(a0,b0,mid2) - F(a1,b1,mid2)))

            l = mid1;

        else

            r = mid2;

    }

  //  cout<<l<<' '<<r<<endl;

    ll ret = inf;

    for (ll i = l; i <= r; i++) {

        //cout<<a0<<' '<<b0<<' '<<a1<<' '<<b1<<endl;

        ret = min(ret,abs(F(a0,b0,i) - F(a1,b1,i)));

    }

    return ret;

}

int main()

{

    while (scanf("%d%d%d%d%d",&n,&m,&S1,&S2,&T) != EOF) {

        if (n == 0 && m == 0) return 0;

        S1--;S2--;T--;

        tot = 0;

        L = 0;

        for (int i = 0; i < n; i++) head[i] = -1;

        for (int i = 0; i < m; i++) {

            int a,b,c;

            scanf("%d%d%s",&a,&b,ss);

            a--;

            b--;

            if (ss[0] == 'x') {

                adde(a,b,-1);

                adde(b,a,-1);

                tot++;

            }

            else {

                c = get(ss);

                adde(a,b,c);

                adde(b,a,c);

            }

        }

        for (int i = 0; i <= tot; i++)

            f[0][i] = f[1][i] = -1;

        spfa(S1,T,0);

        spfa(S2,T,1);

        get(S1,T,f[0],a[0],b[0],0);

        get(S2,T,f[1],a[1],b[1],1);

        //continue;

       // return 0;

        int i,j;

        i = 0,j = 0;

        ll ret = inf1;

        //for (int i = 0; i <= 10; i++)

       //     cout<<f[0][i]<<' '<<a[0][i]<<' '<<b[0][i]<<' '<<f[1][i]<<' '<<a[1][i]<<' '<<b[1][i]<<endl;

        while (1) {

            //cout<<i<<' '<<j<<endl;

            ret = min(ret,cal2(a[0][i],b[0][i],a[1][j],b[1][j],min(f[0][i],f[1][j]),max(f[0][i + 1],f[1][j + 1]) + 1));

            if (f[0][i + 1] == -1 && f[1][j + 1] == -1) break;

            //cout<<'x'<<endl;

            if (f[0][i + 1] > f[1][j + 1])

                i++;

            else

                j++;

        }

        cout<<ret<<endl;

    }

}

// Fastest known solution for this problem: