#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i = a;i<n;i++)
#define ll long long

int main(){
    iostream::sync_with_stdio(false);
    cout<<fixed<<setprecision(9);
	int edges, n, from, to; //od 1
	while(true){
		cin >>edges >>n>>from>>to;
		from--; to--;
		if(edges==0) return 0;
		
		vector<pair<int, ll>> graph[n];
		vector<int> rg[n];
		rep(i,0,edges){
			int a, b;
			double u;
			cin >> a >> b >> u;
			ll len = round(u * 1000);
			graph[a-1].push_back({b-1, -len});
			rg[b-1].push_back(a-1);
		}
		
		vector<bool> rs(n, false);
		queue<int> rq;
		rs[to] = true;
		rq.push(to);
		while(!rq.empty()){
			int cur = rq.front();
			rq.pop();
			for(auto x : rg[cur]){
				if(!rs[x]){
					rs[x] = true;
					rq.push(x);
				}
			}
		}
		if(!rs[from]){
			cout << "FALSE" << endl;
			continue;
		}
		ll INF = 1e17;
		vector<ll> best(n, INF);
		best[from] = 0;
		vector<bool> closed(n, false);
		set<pair<ll,int>> s;
		s.insert({0, from});
		bool done = false;
		while(!s.empty()){ //ignorovat vrcholy, ktere nevedou do cile
			ll dist; int cur;
			tie(dist, cur) = *s.begin();
			//cout << dist << " | " << cur << endl;
			closed[cur] = true;
			s.erase(s.begin());
			for(auto x : graph[cur]) {
				int b; ll len;
				tie(b, len) = x;
				if(!rs[b]) continue;
				ll next = dist + len;
				if(next < best[b]){
					if(closed[b]){ //zlepsili jsme uzavreny vrchol
						//cout << "improved " << b << " from " << best[b] << " to " << next << endl;
						done = true;
						break;
					}
					if(best[b]<INF) s.erase({best[b], b});
					best[b] = next;
					s.insert({next, b});
				}
			}
			if(done) break;
		}
		cout << (done?"TRUE":"FALSE") << endl;
	}
    return 0;
}