#include using namespace std; using ii = pair; struct edge { // Terminal vertex / Weight int v, w; edge(int v, int w) : v(v), w(w) {} }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, s, t; cin >> n >> m >> s >> t; // Edges into each vertex. vector> E(n), RE(n); map EW; while (m--) { int u, v, w; cin >> u >> v >> w; E[u].emplace_back(v, w); RE[v].emplace_back(u, w); EW[{u, v}] = w; } // Dijkstra from t. vector dist_t(n, -1); { priority_queue, greater> pq; pq.push({dist_t[t] = 0, t}); while (!pq.empty()) { int d, u; tie(d, u) = pq.top(); pq.pop(); if (dist_t[u] != d) continue; for (const edge &e : RE[u]) { int nd = d + e.w; if (dist_t[e.v] < 0 || nd < dist_t[e.v]) { dist_t[e.v] = nd; pq.push({nd, e.v}); } } } } // For each vertex find its best and worst outgoing edge. vector best(n, -1), worst(n, -1); for (int i = 0; i < n; ++i) { int f = -1, fi = -1, s = -1, si = -1; for (const edge &e : E[i]) { if (f == -1 || dist_t[e.v]+e.w < f) fi = e.v, f = dist_t[e.v]+e.w; if (s == -1 || dist_t[e.v]+e.w > s) si = e.v, s = dist_t[e.v]+e.w; } if (f >= 0) best[i] = fi; if (s >= 0) worst[i] = si; } int turn = 0, position = s, time = 0; // do 3n steps. for (int st = 0; st < 3 * n; ++st) { if (position == t || best[position] < 0) break; if (turn == 0) { // take worst time += EW[{position, worst[position]}]; position = worst[position]; turn = 1 - turn; } else { // take best time += EW[{position, best[position]}]; position = best[position]; turn = 1 - turn; } } if (position == t) cout << time << endl; else cout << "infinity" << endl; return 0; }