#include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<list>
#include<bitset>
#include<stack>
#include<memory>
#include<numeric>
using namespace std;
using namespace std::chrono;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
const llint mod=1000000007;
const llint big=2.19e15+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-12;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(const vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(const vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}
bool solve(void){
	int n,m,sa,sb,T,i;cin>>n>>m>>sa>>sb>>T;
	if(n==0){return false;}
	sa--;sb--;T--;
	vector<vector<pair<int,llint>>>go(n);
	vector<vector<int>>mo(n);
	while(m--){
		int a,b;cin>>a>>b;a--;b--;
		string s;cin>>s;
		if(s=="x"){mo[a].pub(b);mo[b].pub(a);}
		else{llint x=0;for(auto it:s){x*=10;x+=it-'0';}
			go[a].pub(mp(b,x));go[b].pub(mp(a,x));
		}
	}
	vector<llint>distA[104];
	vector<llint>distB[104];
	for(i=0;i<104;i++){distA[i]=vector<llint>(n,big);distB[i]=distA[i];}
	priority_queue<tuple<llint,int,int>,vector<tuple<llint,int,int>>,greater<tuple<llint,int,int>>>que;
	distA[0][sa]=0;
	que.push(mt(0LL,0,sa));
	while(que.size()){
		llint time;int mg,bas;
		tie(time,mg,bas)=que.top();que.pop();
		if(mg>100||distA[mg][bas]>time){continue;}
		mineq(distA[mg+1][bas],time);
		mineq(distA[mg+2][bas],time);
		for(auto it:go[bas]){
			if(mineq(distA[mg][it.fir],time+it.sec)){que.push(mt(time+it.sec,mg,it.fir));}
		}
		for(auto it:mo[bas]){
			if(mineq(distA[mg+1][it],time)){que.push(mt(time,mg+1,it));}
		}
	}
	
	distB[0][sb]=0;
	que.push(mt(0LL,0,sb));
	while(que.size()){
		llint time;int mg,bas;
		tie(time,mg,bas)=que.top();que.pop();
		if(mg>100||distB[mg][bas]>time){continue;}
		mineq(distB[mg+1][bas],time);
		mineq(distB[mg+2][bas],time);
		for(auto it:go[bas]){
			if(mineq(distB[mg][it.fir],time+it.sec)){que.push(mt(time+it.sec,mg,it.fir));}
		}
		for(auto it:mo[bas]){
			if(mineq(distB[mg+1][it],time)){que.push(mt(time,mg+1,it));}
		}
	}
	//convex full
	vector<tuple<llint,int,llint>>fullA;
	fullA.pub(mt(big+3,0,distA[0][T]));
	for(i=1;i<=100;i++){
		while(-1){
			llint nomdif=get<2>(fullA.back())-distA[i][T];
			if(nomdif<=0){break;}
			llint magdif=i-get<1>(fullA.back());
			llint bord=nomdif/magdif;
			if(get<0>(fullA.back())<=bord){fullA.pob();}
			else{fullA.pub(mt(bord,i,distA[i][T]));break;}
		}
	}
	//cerr<<"fullA"<<endl;
	//for(auto it:fullA){cerr<<get<0>(it)<<" "<<get<1>(it)<<" "<<get<2>(it)<<endl;}
	
	vector<tuple<llint,int,llint>>fullB;
	fullB.pub(mt(big+3,0,distB[0][T]));
	for(i=1;i<=100;i++){
		while(-1){
			llint nomdif=get<2>(fullB.back())-distB[i][T];
			if(nomdif<=0){break;}
			llint magdif=i-get<1>(fullB.back());
			llint bord=nomdif/magdif;
			if(get<0>(fullB.back())<=bord){fullB.pob();}
			else{fullB.pub(mt(bord,i,distB[i][T]));break;}
		}
	}
	//cerr<<"fullB"<<endl;
	//for(auto it:fullB){cerr<<get<0>(it)<<" "<<get<1>(it)<<" "<<get<2>(it)<<endl;}
	
	llint ans=big,Lbri=0;
	while(fullA.size()+fullB.size()>=2){
		llint Ubri=min(get<0>(fullA.back()),get<0>(fullB.back()));
		llint Mdif=get<1>(fullA.back())-get<1>(fullB.back());
		llint Ndif=get<2>(fullA.back())-get<2>(fullB.back());
		//cerr<<"Ndif="<<Ndif<<"Mdif="<<Mdif<<endl;
		if(Lbri>Ubri||get<2>(fullA.back())>big-100||get<2>(fullB.back())>big-100){}
		else if(Mdif==0){mineq(ans,abs(Ndif));}
		else{
			if(Mdif<0){Mdif*=-1;}else{Ndif*=-1;}
			llint Sbri=(Ndif+Ndif+Mdif)/(Mdif+Mdif);//四捨五入
			mineq(Sbri,Ubri);maxeq(Sbri,Lbri);
			mineq(ans,abs(Ndif-Mdif*Sbri));
		}
		Lbri=Ubri+1;
		if(get<0>(fullA.back())<get<0>(fullB.back())){fullA.pob();}
		else{fullB.pob();}
	}
	cout<<ans<<endl;
	return true;
}
int main(void){
	cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);
	while(solve()){}
	return 0;
}



Measured memory_bytes: 4812