#include <bits/stdc++.h>   using namespace std;   const int N = 1111;   const int M = 33333;   const int INF = 2e9 + 9;   int n, m;   int s, t;   int erased_edge;   struct Edge {     int u, v, c;     Edge() {}     Edge(int u, int v, int c) {       this->u = u;       this->v = v;       this->c = c;     }     int to(int node) { return u ^ node ^ v; }   } E[M];   vector<int> a[N];   vector<int> path;   vector<int> findPath() {     queue<int> Q;     vector<int> trace(n + 1, -1);     trace[t] = 0;     Q.push(t);     while (!Q.empty()) {       int u = Q.front();       Q.pop();       for (int e : a[u])         if (erased_edge != e) {           int v = E[e].to(u);           if (trace[v] != -1) continue;           trace[v] = e;           Q.push(v);         }     }     vector<int> ans;     if (trace[s] == -1) return ans;     for (int u = s; u != t; u = E[trace[u]].to(u)) {       ans.push_back(trace[u]);     }     return ans;   }   vector<int> solveOneEdge() {     int best = INF;     int ans = -1;     for (int e : path) {       erased_edge = e;       if (findPath().empty() && best > E[e].c) {         best = E[e].c;         ans = e;       }     }     vector<int> res;     res.push_back(best);     res.push_back(ans);     return res;   }   int timer = 0;   int parent_edge[N], parent_cost[N];   int num[N], low[N];   bool containST[N];   void dfs(int u) {     ;     num[u] = ++timer;     low[u] = INF;     containST[u] = u == t;     for (int e : a[u]) {       if (e == erased_edge || e == parent_edge[u]) continue;       int v = E[e].to(u);       if (num[v]) {         ;         low[u] = min(low[u], num[v]);       } else {         parent_edge[v] = e;         parent_cost[v] = E[e].c;         dfs(v);         low[u] = min(low[u], low[v]);         containST[u] |= containST[v];       }     }   }   vector<int> solveTwoEdge() {     int best = INF;     int ans1 = -1, ans2 = -1;     for (int e : path) {       erased_edge = e;       timer = 0;       fill(parent_edge + 1, parent_edge + n + 1, 0);       fill(num + 1, num + n + 1, 0);       fill(containST + 1, containST + n + 1, 0);       parent_edge[s] = -1;       ;       dfs(s);       for (int v = 1; v <= n; ++v)         if (v != s && low[v] >= num[v] && containST[v]) {           if (best > E[erased_edge].c + parent_cost[v]) {             best = E[erased_edge].c + parent_cost[v];             ans1 = erased_edge;             ans2 = parent_edge[v];           };           ;         }     }     vector<int> res;     res.push_back(best);     res.push_back(ans1);     res.push_back(ans2);     return res;   }   int main() {     ios_base ::sync_with_stdio(0);     cin >> n >> m;     cin >> s >> t;     for (int i = 1; i <= m; ++i) {       int u, v, c;       cin >> u >> v >> c;       E[i] = Edge(u, v, c);       a[u].push_back(i);       a[v].push_back(i);     }     ::path = findPath();     ;     if (::path.empty()) {       cout << 0 <<   n  << 0 <<   n ;       return 0;     }     vector<int> one = solveOneEdge();     vector<int> two = solveTwoEdge();     int mn = min(one[0], two[0]);     if (mn == INF) {       cout <<  -1 n ;       return 0;     }     if (one[0] < two[0]) {       cout << one[0] <<   n  << 1 <<   n  << one[1] <<   n ;       return 0;     }     cout << two[0] <<   n  << 2 <<   n  << two[1] <<     << two[2] <<   n ;   }