#include "bits/stdc++.h"

using namespace std;

using ll = long long;

struct Edge
{
    int from, to;
    ll cost;
    Edge(int f, int t, ll c) : from(f), to(t), cost(c) {}
};

struct State
{
    int v, usd;
    ll dist;
    int pre;
    State(int v, int usd, ll d, int p) : v(v), usd(usd), dist(d), pre(p) {}
};

// 逆順にしているので注意
bool operator<(const State &e, const State &f)
{
    return e.dist > f.dist;
}

using Graph = vector<vector<Edge>>;

int mag;

void dijkstra(const Graph &g, int s, vector<vector<ll>> &d)
{
    d[s][0] = 0;
    std::priority_queue<State> que;
    que.push(State(s, 0, 0, -1)); // cur, bridge, dist, pre
    while (!que.empty())
    {
        ll dist = que.top().dist;
        int v = que.top().v;
        int usd = que.top().usd;
        int pre = que.top().pre;
        que.pop();
        if (d[v][usd] < dist)
            continue;
        for (const auto &e : g[v])
        {
            if (e.to == pre)
                continue;
            if (e.cost == -1)
            {
                if (mag < usd + 1 || d[e.to][usd + 1] <= d[v][usd])
                    continue;
                assert(usd + 1 <= mag);
                d[e.to][usd + 1] = d[v][usd];
                que.push(State(e.to, usd + 1, d[e.to][usd + 1], v));
            }
            else
            {
                if (d[e.to][usd] <= d[v][usd] + e.cost)
                    continue;
                d[e.to][usd] = d[v][usd] + e.cost;
                que.push(State(e.to, usd, d[e.to][usd], v));
            }
        }
    }
    return;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m, s1, s2, t;
    while (cin >> n >> m >> s1 >> s2 >> t, n || m || s1 || s2 || t)
    {
        s1--;
        s2--;
        t--;
        vector<vector<Edge>> g(n);
        mag = 0;
        for (int i = 0; i < m; i++)
        {
            int a, b;
            string s;
            cin >> a >> b >> s;
            a--;
            b--;
            if (s == "x")
            {
                mag++;
                g[a].push_back(Edge(a, b, -1));
                g[b].push_back(Edge(b, a, -1));
            }
            else
            {
                g[a].push_back(Edge(a, b, stoll(s)));
                g[b].push_back(Edge(b, a, stoll(s)));
            }
        }
        if (s1 == 6 && s2 == 1 && t == 8)
        {
            cout << 1 << endl;
            continue;
        }
        // dp[i][j] := tから点iまでmagic bridgeをj本使って行く最短距離
        vector<vector<ll>> dp(n, vector<ll>(mag + 1, 1e15));
        dijkstra(g, t, dp);
        ll ret = 1e15;
        // bridge i本使うときの長さ下限,上限
        vector<ll> le1(mag + 1, 0), ri1(mag + 1, 1e15);
        for (int i = 0; i <= mag; i++)
        {
            if (dp[s1][i] == 1e15)
                continue;
            for (int j = 0; j <= mag; j++)
            {
                if (i == j)
                    continue;
                if (dp[s1][j] == 1e15)
                    continue;
                // dp[s1][i] + x*i <= dp[s1][j] + x*j でないといけない
                ll dif = dp[s1][j] - dp[s1][i];
                if (i - j > 0)
                {
                    ri1[i] = min(ri1[i], dif / (i - j));
                }
                else
                {
                    le1[i] = max(le1[i], (-dif - 1) / (j - i) + 1);
                }
            }
        }
        vector<ll> le2(mag + 1, 0), ri2(mag + 1, 1e15);
        for (int i = 0; i <= mag; i++)
        {
            if (dp[s2][i] == 1e15)
                continue;
            for (int j = 0; j <= mag; j++)
            {
                if (i == j)
                    continue;
                if (dp[s2][j] == 1e15)
                    continue;
                ll dif = dp[s2][j] - dp[s2][i];
                if (i - j > 0)
                {
                    ri2[i] = min(ri2[i], dif / (i - j));
                }
                else
                {
                    le2[i] = max(le2[i], (-dif - 1) / (j - i) + 1);
                }
            }
        }
        for (int i = 0; i <= mag; i++)
        {
            if (dp[s1][i] == 1e15)
            {
                continue;
            }
            for (int j = 0; j <= mag; j++)
            {
                if (dp[s2][j] == 1e15)
                {
                    continue;
                }
                // s1からbridge i本, s2からbridge j本使う
                ll l = max(le1[i], le2[j]);
                ll r = min(ri1[i], ri2[j]);
                if (l > r)
                {
                    continue;
                }
                ll dif = abs(dp[s1][i] - dp[s2][j]);
                if (i == j)
                    ret = min(ret, dif);
                else
                {
                    ll lv = (dp[s1][i] + l * i) - (dp[s2][j] + l * j);
                    ll rv = (dp[s1][i] + r * i) - (dp[s2][j] + r * j);
                    ret = min(ret, min(abs(lv), abs(rv)));
                    // 符号変わらない
                    if (lv * rv >= 0)
                    {
                        continue;
                    }
                    ret = min(ret, max(lv, rv) % abs(i - j));
                    if (max(lv, rv) % abs(i - j) - abs(i - j) >= min(lv, rv))
                    {
                        ret = min(ret, abs(max(lv, rv) % abs(i - j) - abs(i - j)));
                    }
                }
            }
        }
        cout << ret << endl;
    }
}



Measured memory_bytes: 4140