#include using namespace std; using ll = long long; #define dmp(x) cerr << __LINE__ << " " << #x << " " << x << endl; #define line(obj) for (auto itr = begin(obj); itr != end(obj); itr++) s << ((itr == begin(obj)) ? "" : ", ") << *itr template ostream& operator<<(ostream& s, const pair& p) { s << "("; s << p.first << ", " << p.second; s << ")"; return s; } template ostream& operator<<(ostream& s, const vector& v) { s << "["; line(v); s << "]"; return s; } template ostream& operator<<(ostream& s, const vector>& vv) { s << "["; line(vv); s << "]"; return s; } template ostream& operator<<(ostream& s, const map& m) { s << "{"; line(m); s << "}"; return s; } template struct Dijkstra { struct Edge { int to; T cost; }; vector prev; vector> g; Dijkstra(int n) : prev(n, -1), g(n) {} void addEdge(int u, int v, T w) { g[u].push_back({v, w}); g[v].push_back({u, w}); } vector build(int s) { vector dist(g.size(), -1); using Node = pair; priority_queue, greater> pq; pq.push({dist[s] = 0, s}); while (!pq.empty()) { auto d = pq.top().first; auto u = pq.top().second; pq.pop(); if (dist[u] < d) continue; for (auto&& v : g[u]) { if (dist[v.to] < 0 || dist[v.to] > dist[u] + v.cost) { dist[v.to] = dist[u] + v.cost; prev[v.to] = u; pq.push({dist[v.to], v.to}); } } } return dist; } vector getPath(int t) { vector path; for (; t != -1; t = prev[t]) path.push_back(t); reverse(begin(path), end(path)); return path; } }; int main() { int n, m, p, q, t; cin >> n >> m >> p >> q >> t, p--, q--; Dijkstra g(n); for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c, a--, b--; g.addEdge(a, b, c); } auto zs = g.build(0); auto ps = g.build(p); auto qs = g.build(q); if (zs[p] + zs[q] + ps[q] <= t) { cout << t << endl; return 0; } ll ans = -1; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { ll mx = max(ps[i] + ps[j], qs[i] + qs[j]); if (zs[i] + zs[j] + mx > t) continue; ans = max(ans, t - mx); } } cout << ans << endl; }