// Template {{{
#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define dump(x) 
#endif

class range {
    struct Iterator {
        int val, inc;
        int operator*() {return val;}
        bool operator!=(Iterator& rhs) {return val < rhs.val;}
        void operator++() {val += inc;}
    };
    Iterator i, n;
    public:
    range(int e) : i({0, 1}), n({e, 1}) {}
    range(int b, int e) : i({b, 1}), n({e, 1}) {}
    range(int b, int e, int inc) : i({b, inc}), n({e, inc}) {}
    Iterator& begin() {return i;}
    Iterator& end() {return n;}
};

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.setf(ios::fixed);
    cout.precision(12);
}
//}}}

struct Edge{
    int dst;
    LL cost;
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;
Graph G;
int N, M, S1, S2, T;
int MB;
const LL INF = 1e18;
vector<LL> calc_cost(int s, int t) {
    LL dist[1000][101] = {};
    typedef tuple<LL, int, int> TP;
    priority_queue<TP, vector<TP>, greater<TP>> que;
    REP(i, N) REP(j, MB+1) dist[i][j] = INF;
    dist[s][0] = 0;
    que.push(TP(0, s, 0));
    while(!que.empty()) {
        LL d;
        int u, c;
        tie(d, u, c) = que.top(); que.pop();
        for(Edge e : G[u]) {
            const int nu = e.dst;
            const int nc = c + (e.cost == -1 ? 1 : 0);
            const LL nd = d + (e.cost == -1 ? 0 : e.cost);
            if(nc <= MB && dist[nu][nc] > nd) {
                dist[nu][nc] = nd;
                que.push(TP(nd, nu, nc));
            }
        }
    }
    vector<LL> res(MB+1);
    REP(i, MB+1) res[i] = dist[t][i];
    return res;
}
// O(N)
LL get(vector<LL> cs, LL X) {
    LL res = cs[0];
    for(int i = 1; i < cs.size(); i++) {
        res = min(res, cs[i] + i * X);
    }
    return res;
}
// O(N)
LL calc_diff(vector<LL> cs1, vector<LL> cs2, LL X) {
    LL cost1 = get(cs1, X);
    LL cost2 = get(cs2, X);
    return abs(cost1 - cost2);
}
int main(){
    iostream_init();
    while(cin >> N >> M >> S1 >> S2 >> T && N > 0) {
        MB = 0;
        S1--; S2--; T--;
        G.assign(N, Node());
        REP(i, M) {
            int a, b;
            cin >> a >> b;
            string ws;
            cin >> ws;
            LL w;
            if(ws == "x") {
                w = -1;
                MB++;
            } else {
                w = stoll(ws);
            }
            a--; b--;
            G[a].push_back({b, w});
            G[b].push_back({a, w});
        }
        vector<LL> cs1 = calc_cost(S1, T);
        // REP(i, cs1.size()) cout << cs1[i] << " "; cout << endl;
        vector<LL> cs2 = calc_cost(S2, T);
        // REP(i, cs2.size()) cout << cs2[i] << " "; cout << endl;
        LL ans = calc_diff(cs1, cs2, 0);
        REP(i, cs1.size()) REP(j, cs1.size()) if(i < j && cs1[i] < INF && cs1[j] < INF) {
            // cs[i] + i * X == cs[j] + j * X
            // cs[i] - cs[j] == (j-i) * X
            LL X = (cs1[i] - cs1[j]) / (j-i);
            // cout << "X: " << X << endl;
            for(LL dx = -1; dx <= 1; dx++) {
                if(X + dx >= 0) ans = min(ans, calc_diff(cs1, cs2, X+dx));
            }
        }
        REP(i, cs2.size()) REP(j, cs2.size()) if(i < j && cs2[i] < INF && cs2[j] < INF) {
            // cs[i] + i * X == cs[j] + j * X
            // cs[i] - cs[j] == (j-i) * X
            LL X = (cs2[i] - cs2[j]) / (j-i);
            // cout << "X: " << X << endl;
            for(LL dx = -1; dx <= 1; dx++) {
                if(X + dx >= 0) ans = min(ans, calc_diff(cs1, cs2, X+dx));
            }
        }
        REP(i, cs2.size()) REP(j, cs1.size()) if(i != j && cs2[i] < INF && cs1[j] < INF) {
            // cs[i] + i * X == cs[j] + j * X
            // cs[i] - cs[j] == (j-i) * X
            LL X = (cs2[i] - cs1[j]) / (j-i);
            // cout << "X: " << X << endl;
            for(LL dx = -1; dx <= 1; dx++) {
                if(X + dx >= 0) ans = min(ans, calc_diff(cs1, cs2, X+dx));
            }
        }
        cout << ans << endl;
    }
    return 0;
}

/* vim:set foldmethod=marker: */

Measured memory_bytes: 4164