#include #define INF 0x7FFFFFFF using namespace std; using ll = long long; using pll = pair; using graph = vector>; const int MAXN = 510; vector dijk(int x, graph& g) { priority_queue pq; pq.push({0, x}); vector dist(MAXN, INF); while (pq.size()){ auto [w, v] = pq.top(); pq.pop(); w = -w; if (dist[v] <= w) continue; dist[v] = w; for (auto [u, ww] : g[v]) { if (dist[u] <= w + ww) continue; pq.push({-(w+ww), u}); } } return dist; } ll almost_dijk(int s, int d, graph& g, vector& dist_s, vector& dist_d) { ll best = dist_s[d]; if (best == INF) return -1; priority_queue pq; pq.push({0, s}); vector dist(MAXN, INF); while (pq.size()){ auto [w, v] = pq.top(); pq.pop(); w = -w; if (v == d) return w; if (dist[v] <= w) continue; dist[v] = w; for (auto [u, ww] : g[v]) { if (dist_s[v] + ww + dist_d[u] <= best) continue; // pula essa aresta, corresponde a um caminho minimo if (dist[u] <= w + ww) continue; pq.push({-(w+ww), u}); } } return -1; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, m; while (cin>>n>>m, n!=0 && m!=0){ int s, d; cin >> s >> d; vector> g(MAXN); vector> g_rev(MAXN); for (int i=0;i> u >> v >> p; g[u].push_back({v, p}); g_rev[v].push_back({u, p}); } vector dist_s = dijk(s, g); vector dist_d = dijk(d, g_rev); cout << almost_dijk(s, d, g, dist_s, dist_d) << '\n'; } }