#include <bits/stdc++.h>
#define FOR(i,l,r) for(int i = l ; i <= r ; i ++)
#define FORD(i,r,l) for(int i = r ; i >= l ; i --)
#define REP(i, a ) for(int i = 0 ; i < a ; i ++ )
#define compare(v) sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end());
#define ll long long
#define el "\n"
#define fi first
#define se second
#define _ROOT_ int main()
#define M 1000000007
#define MAXN 1000001
#define INF (1ll<<60)
#define NAME "file"
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;

ll n, m, q, m_1, m_2, s, t, ans = INF ;
ll a[MAXN] ;
ll lab[MAXN ] ;

struct Edge {
    ll u, v, w ;
    bool operator < (const Edge & other ) const {
        return w < other.w ;
    }
};
Edge A[MAXN], B[MAXN ] ;

struct Data {
    ll u, v, sz_u, sz_v ;
};
stack<Data> history ;

ll find_set(ll a ) {
    return lab[a] < 0 ? a : find_set(lab[a]) ;
}
ll same_set(ll a, ll b ) {
    return find_set(a) == find_set(b) ;
}
bool union_set(ll a, ll b ) {
    a = find_set(a) ;
    b = find_set(b) ;
    if(a == b ) return false ;
    if(lab[a] > lab[b]) swap(a, b ) ;
    history.push({a, b, lab[a], lab[b] }) ;
    lab[a] += lab[b] ;
    lab[b] = a;
    return true ;
}

ll snapshot() {
    return history.size() ;
}

void rollBack(ll time ) {
    while(history.size() > time ) {
        Data u = history.top() ;
        lab[u.u] = u.sz_u ;
        lab[u.v] = u.sz_v ;
        history.pop() ;
    }
}

void dnc(ll l1, ll r1, ll l2, ll r2 ) {
    if(l1 > r1 || l2 > r2 ) return ;
    ll snap = snapshot() ;
    ll mid = l1 + r1 >> 1 ;
    FOR(i, l1, mid ) union_set(A[i].u, A[i].v ) ;
    ll fmid = -1 ;
    FOR(i, l2, r2 ) {
        union_set(B[i].u, B[i].v ) ;
        if(same_set(s, t )) {
            fmid = i ;
            break ;
        }
    }

    if(fmid != -1 ) {
        ans = min(ans, B[fmid].w + A[mid].w ) ;
    }
    rollBack(snap ) ;
    if(l1 == r1 ) return ;

    FOR(i, l1, mid ) union_set(A[i].u, A[i].v ) ;

    if(fmid == -1 ) {
        dnc(mid + 1, r1, l2, r2 ) ;
    } else {
        dnc(mid + 1, r1, l2, fmid ) ;
    }
    rollBack(snap ) ;

    if(fmid != -1 ) {
        FOR(i, l2, fmid - 1 ) union_set(B[i].u, B[i].v ) ;
        dnc(l1, mid, fmid, r2 ) ;
        rollBack(snap ) ;
    }
}

void init() {
    cin >> n >> m >> s >> t ;
    FOR(i, 1, m ) {
        ll t, u, v, w ;
        cin >> t >> u >> v >> w ;
        if(t == 1 ) {
            m_1 ++ ;
            A[m_1] = {u, v, w } ;
        } else {
            m_2 ++ ;
            B[m_2] = {u, v, w } ;
        }
    }
    sort(A + 1, A + m_1 + 1 ) ;
    sort(B + 1, B + m_2 + 1 ) ;
}

void solve() {
    memset(lab, -1, sizeof lab ) ;

    FOR(i, 1, m_2 ) {
        union_set(B[i].u, B[i].v ) ;
        if(same_set(s, t )) {
            ans = min(B[i].w , ans ) ;
            break ;
        }
    }
    rollBack(0) ;
    FOR(i, 1, m_1 ) {
        union_set(A[i].u, A[i].v ) ;
        if(same_set(s, t )) {
            ans = min(A[i].w , ans ) ;
            break ;
        }
    }
    rollBack(0) ;
    dnc(1, m_1, 1, m_2 ) ;
    cout << ans << el ;
}

_ROOT_ {
    // freopen(NAME".inp" , "r" , stdin);
    // freopen(NAME".out" , "w", stdout) ;
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1; // cin >> t ;
    while(t--) {
        init();
        solve();
    }
    return (0&0);
}
