#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

vector<pii> g[1000];
ll dist[1000][101];

struct P {
  int v,c;
  ll d;
  P(int v, int c, ll d):v(v),c(c),d(d) {
  }
  bool operator<(const P &rhs) const {
    return d>rhs.d;
  }
};
int n,m,s1,s2,t;

vector<ll> func(int s) {
  priority_queue<P> Q;
  Q.push(P(s,0,0));
  REP(i,n)REP(j,101)dist[i][j] = 1LL<<60;
  dist[s][0] = 0;
  while(!Q.empty()) {
    P p = Q.top(); Q.pop();
    if (dist[p.v][p.c] < p.d) continue;
    FOR(it, g[p.v]) {
      ll nd = p.d;
      int nc = p.c;
      if (it->second == -1) {
        nc++;
      } else {
        nd += it->second;
      }
      if (nc > 100) continue;
      if (dist[it->first][nc] > nd) {
        dist[it->first][nc] = nd;
        Q.push(P(it->first,nc,nd));
      }
    }
  }
  vector<ll> res;
  REP(i,101) {
    res.push_back(dist[t][i]);
  }
  return res;
}

vector<ll> func2(vector<ll> v) {
  vector<ll> res;
  REP(i,v.size()) {
    if (v[i] == 1LL<<60) continue;
    REP(j,i) {
      if (v[j] == 1LL<<60) continue;
      // v[i]+i*x = v[j]+j*x
      double x = -(v[i]-v[j])/(i-j);
      if (x < 0) continue;
      res.push_back((ll)x);
      res.push_back((ll)(x+1));
    }
  }
  return res;
}

int main() {  
  while(cin>>n>>m>>s1>>s2>>t,n) {
    s1--;s2--;t--;
    REP(i,n) g[i].clear();
    REP(i,m) {
      int a,b;
      string s;
      cin >> a >> b >> s;
      a--;b--;
      int d;
      if (s == "x") {
        d = -1;
      } else {
        d = atoi(s.c_str());
      }
      g[a].push_back(pii(b,d));
      g[b].push_back(pii(a,d));
    }
    vector<ll> v1 = func(s1);
    vector<ll> v2 = func(s2);
    vector<ll> xs = func2(v1);
    vector<ll> xs2 = func2(v2);
    FOR(it, xs2) xs.push_back(*it);
    REP(i,v1.size()) {
      if (v1[i] == INF) continue;
      REP(j,v2.size()) {
        if (v2[j] == INF) continue;
        if (i==j) continue;
        double x = -(v1[i]-v2[j])/(i-j);
        if (x < 0) continue;
        xs.push_back((ll)x);
        xs.push_back((ll)(x+1));        
      }
    }
    // REP(i,3) {
    //   cout << i << " " << v1[i] << " " << v2[i]<< endl;
    // }    
    xs.push_back(0);
    sort(ALL(xs));
    xs.erase(unique(ALL(xs)), xs.end());
    ll res = 1LL<<61;
    FOR(it, xs) {
      ll x = *it;
      ll y1 = 1LL<<61;
      REP(i,v1.size()) {
        if (v1[i] == 1LL<<60) continue;
        chmin(y1,v1[i]+i*x);
      }
      ll y2 = 1LL<<61;
      REP(i,v2.size()) {
        if (v2[i] == 1LL<<60) continue;
        chmin(y2,v2[i]+i*x);
      }
      chmin(res, abs(y1-y2));
    }
    cout << res << endl;
  }
}

Measured memory_bytes: 4104