#include using namespace std; #define x first #define y second #define pb push_back #define eb emplace_back #define rep(i,a,b) for(auto i = (a); i != (b); ++i) #define REP(i,n) rep(i,0,n) #define all(v) (v).begin(), (v).end() typedef long long ll; typedef long double ld; typedef pair ii; typedef vector vi; typedef vector vvi; typedef vector vii; const int maxn = 1e5; const int maxm = 2e5; const int INF = 2e9; int N, M, S, T; struct edge { int fr, to, time; }; edge g[maxm]; // ub: the latest time the maximize half can achieve // lb: the earliest time the minimize half can achieve int ub[maxn], lb[maxn]; // pu: previous maximum // pl previous minimum int pu[maxn], pl[maxn]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N >> M >> S >> T; REP(i, M) cin >> g[i].fr >> g[i].to >> g[i].time; fill_n(ub, N, -INF); fill_n(lb, N, INF); ub[T] = 0; // starting point. lb[T] = 0; bool done; int nupdates_sub = 0; do { done = true; REP(idx, M) { int j = g[idx].fr; int i = g[idx].to; int t = g[idx].time; // try i -> j (time t) if (lb[i] != INF && (lb[i] + t > ub[j] || (pu[j] == i && lb[i] + t != ub[j]))) { int old_time = ub[j]; ub[j] = lb[i] + t; if (j == S && ub[j] > old_time && ++nupdates_sub > N) { // increased more than once: // cerr << "NEW TIME: " << old_time << " -> " << ub[j] << endl; cout << "infinity" << endl; exit(0); } pu[j] = i; done = false; } if (ub[i] != -INF && (ub[i] + t < lb[j] || (pl[j] == i && ub[i] + t != lb[j]))) { lb[j] = ub[i] + t; pl[j] = i; done = false; } } } while (!done); REP(i, N) cerr << lb[i] << " " << ub[i] << endl; // cout << lb[S] << " " << ub[S] << endl; cout << ub[S] << endl; // cerr << endl; return 0; }