#include <iostream>
#include <string>
#include <numeric>
#include <vector>
#include <cstdio>
#include <limits>
#include <algorithm>

//#define plankton

#ifndef plankton
#define debug


struct Food {
    std::vector<int> links;
    bool visited = false;
    bool reachable = false;
};

std::vector<int> negative_starts;


std::vector<Food> foods;
std::vector<int> visited;
std::vector<int> vec;
std::vector<double> tab;
int F;
inline double& at(int from, int to) {
    return tab.at(from*F + to);
}

inline void dfs_reinit() {
    for (auto& f : foods) {
        f.visited = false;
    }
}

inline void dfs(int current){
    if (foods[current].visited){
        return;
    }

    foods[current].visited = true;

    for (int i : foods[current].links){
        dfs(i);
    }
}

inline void dfs_reachable(int current){
    if (foods[current].reachable){
        return;
    }

    foods[current].reachable = true;

    for (int i : foods[current].links){
        dfs_reachable(i);
    }
}

void FW() {
    for (int k : vec){
        for (int i : vec){
            for (int j : vec){
                auto sum = at(i, k) + at(k, j);
                if (sum < at(i, j)){
                    at(i, j) = sum;
                }
            }
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    int Fu, Fn, T;
    while (std::cin >> T >> F >> Fu >> Fn) {
        if (F == 0) break;
        Fu--; Fn--;
        tab.clear();
        tab.resize(F*F, std::numeric_limits<double>::max());

        foods.clear();
        foods.resize(F);

        vec.resize(F);

        for (int f = 0; f < F; ++f) {
            at(f,f) = 0;
        }

        for (int t = 0; t < T; ++t) {
            int Fr, Fg;
            double U;
            std::cin >> Fr >> Fg >> U;
            Fr--; Fg--;
            at(Fr, Fg) = -U;
            foods.at(Fr).links.push_back(Fg);
        }

        //dfs_reinit();
        dfs_reachable(Fu);

        if (!foods[Fn].reachable){
            std::cout << "FALSE\n";
            continue;
        }


        std::iota(begin(vec), end(vec), 0);

        vec.erase(std::remove_if(begin(vec), end(vec), [&](int i){
            return !foods[i].reachable;
        }), end(vec));

        FW();

        bool has_loop = false;


        negative_starts.clear();

        for (int i = 0; i < F; ++i){
            if (!foods[i].reachable) continue;
            if (at(i, i) < 0){
                negative_starts.push_back(i);
            }
        }

        //dfs_reinit();
        for (int i : negative_starts){
            dfs(i);
            if (foods[Fn].visited){
                has_loop = true;
                break;
            }
        }

        if (has_loop){
            std::cout << "TRUE\n";
        } else {
            std::cout << "FALSE\n";
        }

    }
}

#endif