// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

int N, M, S, T, U, V;
using Graph = vector< vector< pair<int, int> > >;
using Queue = priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > >;

vector<int> dijkstra(Graph &G, int root) {
    vector<int> dist(N, INF);
    dist[root] = 0;

    Queue que;
    que.emplace(0, root);
    while(que.size()) {
        int d, pos; tie(d, pos) = que.top(); que.pop();
        if(dist[pos] < d) continue;
        for(auto e : G[pos]) {
            int to, w; tie(to, w) = e;
            if(dist[to] > d + w) {
                dist[to] = d + w;
                que.emplace(d + w, to);
            }
        }
    }
    return dist;
}

int solve(Graph &G, vector<int> distU, vector<int> distV) {
    // dp1 := U から i まで到達するために必要なコスト (S-T 最短パスに含まれるところに関してはコストを 0 とする)
    // dp2 := U から x まで進み、S-T 最短パスに含まれる x-y パスを S から遠ざかるように通って、y から V まで進むときのコスト最小

    // dp3 := V から i まで到達するために必要なコスト (S-T 最短パスに含まれるところに関してはコストを 0 とする)
    // dp4 := V から x まで進み、S-T 最短パスに含まれる x-y パスを S から遠ざかるように通って、y から U まで進むときのコスト最小
    vector<int> dp1(N), dp2(N, INF), dp3(N), dp4(N, INF), dist(N, INF);
    for(int i=0; i<N; i++) {
        dp1[i] = distU[i];
        dp3[i] = distV[i];
    }

    Queue que;
    que.emplace(0, S);
    dist[S] = 0;
    while(que.size()) {
        int d, pos; tie(d, pos) = que.top(); que.pop();
        if(dist[pos] < d) continue;
        for(auto e : G[pos]) {
            int pre, w; tie(pre, w) = e;
            // d(S, pre) + d(pre, pos) = d(S, pos) ならば、
            // その辺は S-pos 最短パスに含まれる辺であるため、
            // 辺のコストを無視できる
            if(dist[pre] + w == dist[pos]) {
                chmin(dp1[pos], dp1[pre]);
                chmin(dp3[pos], dp3[pre]);
            }
        }
        // pos から全て真面目にコストがかかったとする場合
        chmin(dp2[pos], dp1[pos] + distV[pos]);
        chmin(dp4[pos], dp3[pos] + distU[pos]);
        for(auto e : G[pos]) {
            int adj, w; tie(adj, w) = e;
            // dp2, dp4 の最適値を受け渡す
            // こうすることで答えが dp[T] に現れるようになる
            if(dist[adj] + w == dist[pos]) {
                chmin(dp2[pos], dp2[adj]);
                chmin(dp4[pos], dp4[adj]);
            }

            if(dist[adj] > d + w) {
                dist[adj] = d + w;
                que.emplace(dist[adj], adj);
            }
        }
    }

    return min(dp2[T], dp4[T]);
}
 
signed main() {
    cin >> N >> M >> S >> T >> U >> V;
    S--, T--, U--, V--;
    Graph G(N);
    for(int i=0; i<M; i++) {
        int u, v, w; scanf("%lld%lld%lld", &u, &v, &w);
        u--; v--;
        G[u].emplace_back(v, w);
        G[v].emplace_back(u, w);
    }

    auto distU = dijkstra(G, U), distV = dijkstra(G, V);
    cout << min(distU[V], solve(G, distU, distV)) << endl;
    return 0;
}



Measured memory_bytes: 25812