#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;


using T = pair<ll, pair<int,int>> ;
void solve(int n){
    int m,s1,s2,t;
    cin>>m>>s1>>s2>>t;
    --s1;--s2;--t;
    vector<vector<pair<int,ll>>> v(n);
    rep(i,m){
        int x,y;
        cin>>x>>y;
        --x;--y;
        string s;
        cin>>s;
        if(s=="x"){
            v[x].emplace_back(y,-1);
            v[y].emplace_back(x,-1);
        }
        else {
            int z=stoi(s);
            v[x].emplace_back(y,z);
            v[y].emplace_back(x,z);
        }
    }
    vector<vector<ll>> dist(n,vector<ll>(111,longinf));
    dist[t][0]=0;
    priority_queue<T,vector<T>, greater<T>> que;
    que.push({0,{t,0}});
    while(que.size()){
        auto p = que.top();que.pop();
        ll d=p.first, cur=p.second.first,cnt=p.second.second;
        if(dist[cur][cnt]<d)continue;
        for(auto to : v[cur]){
            int nxt=to.first, cost=to.second;
            if(cost==-1){
                if(cnt<=100&&d<dist[nxt][cnt+1]){
                    dist[nxt][cnt+1]=d;
                    que.push({d,{nxt,cnt+1}});
                }
            }
            else {
               if(d+cost<dist[nxt][cnt]){
                    dist[nxt][cnt]=d+cost;
                    que.push({d+cost,{nxt,cnt}});
                } 
            }
        }
    }

    vector<pair<ll,ll>> r1(111,{0,longinf}),r2(111,{0,longinf});
    rep(i,101){
        REP(j,i+1,101){
            if(dist[s1][i]<dist[s1][j]){
                r1[j]={0,-1};continue;
            }
            ll x = (dist[s1][i]-dist[s1][j])/(j-i);
            r1[j].second=min(r1[j].second, x);
            x = (dist[s1][i]-dist[s1][j]+j-i-1)/(j-i);
            r1[i].first = max(r1[i].first, x);
        }
    }

    rep(i,101){
        REP(j,i+1,101){
            if(dist[s2][i]<dist[s2][j]){
                r2[j]={0,-1};continue;
            }
            ll x = (dist[s2][i]-dist[s2][j])/(j-i);
            r2[j].second=min(r2[j].second, x);
            x = (dist[s2][i]-dist[s2][j]+j-i-1)/(j-i);
            r2[i].first = max(r2[i].first, x);
        }
    }
    ll ans=longinf;
    rep(i,101)rep(j,101){
        ll l=max(r1[i].first,r2[j].first), r=min(r1[i].second, r2[j].second);
        if(l>r||dist[s1][i]==longinf||dist[s2][j]==longinf)continue;
        ll ret=abs(dist[s1][i]+i*l-dist[s2][j]-j*l);
        ret=min(abs(dist[s1][i]+i*r-dist[s2][j]-j*r),ret);
        if(i!=j){
            ll x = (dist[s1][i]-dist[s2][j])/(j-i);
            if(l<=x&&x<=r){
                ret=min(abs(dist[s1][i]+i*x-dist[s2][j]-j*x),ret);
            }
            ++x;
            if(l<=x&&x<=r){
                ret=min(abs(dist[s1][i]+i*x-dist[s2][j]-j*x),ret);
            }
            x-=2;
            if(l<=x&&x<=r){
                ret=min(abs(dist[s1][i]+i*x-dist[s2][j]-j*x),ret);
            }
        }
        ans=min(ans,ret);
    }
    cout<<ans<<endl;
}
int main(){
    int n;
    while(cin>>n,n!=0)solve(n);
    return 0;
}


Measured memory_bytes: 5820