#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 100005
#define INF (1ll<<30)
#define NAME "TAITRONG"
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;

struct edge {
    ll u, v, w;
};

ll n, m, s, t;
vector<edge> edges;
ll lab[MAXN];

ll find_set(ll v) {
    if (lab[v] < 0) return v;
    return lab[v] = find_set(lab[v]);
}

bool union_sets(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);
    lab[a] += lab[b];
    lab[b] = a;
    return true ;
}

bool check(ll val) {

    FOR(i, 1, n) lab[i] = -1;

    for (auto e : edges) {
        if (e.w >= val) {
            union_sets(e.u, e.v);
        }
    }
    return find_set(s) == find_set(t);
}

void init() {
    cin >> n >> m >> s >> t ;
    REP(i, m) {
        ll u, v, w;
        cin >> u >> v >> w;
        edges.push_back({u, v, w});
    }
}

void solve() {
    ll l = 1, r = 10000, ans = 0;
    while(l <= r) {
        ll mid = (l + r) / 2;
        if (check(mid)) {
            ans = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    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);
}
