#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define pb push_back
#define mp make_pair
using namespace std;
const int lmax=1000004,nmax=250004,DIM=100000;
int poz=DIM-1;
char buff[DIM];
void citeste(int &nr)
{
nr=0;
while(!('0'<=buff[poz]&&buff[poz]<='9'))
{
if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
}
while('0'<=buff[poz]&&buff[poz]<='9')
{
nr=nr*10 + buff[poz]-'0';
if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
}
}
struct str
{
int nod;
int cst;
bool operator <(const str &aux) const
{
return cst<aux.cst;
}
}aint[lmax];
str miin(str a,str b)
{
if(a<b) return a;
return b;
}
vector< pair<int,int> > adj[nmax];
int n,m,x,y;
int cost[nmax],vis[nmax];
void update(int poz)
{
str tmp;
tmp.nod=poz;
tmp.cst=cost[poz];
poz=poz-1+n;
aint[poz]=tmp;
for(poz>>=1;poz>=1;poz>>=1) aint[poz]=min(aint[(poz<<1)],aint[(poz<<1)|1]);
}
void dijkstra()
{
for(int xyz=1;xyz<=n;xyz++)
{
int nod=aint[1].nod,cc=aint[1].cst;
if(nod==y) break;
// printf("%d\n",nod);
cost[nod]=0x3f3f3f + 5;
update(nod);
cost[nod]=cc;
for(vector< pair<int,int> >::iterator it=adj[nod].begin();it!=adj[nod].end();++it)
{
if(cost[(*it).first]>max(cost[nod],(*it).second))
{
cost[(*it).first]=max(cost[nod],(*it).second);
update((*it).first);
}
}
}
}
int main()
{
freopen ("pscnv.in","r",stdin);
freopen ("pscnv.out","w",stdout);
citeste(n),citeste(m),citeste(x),citeste(y);
for(int i=1;i<=n;i++) cost[i]=0x3f3f3f3f;
cost[x]=0;
for(int i=1;i<=n;i++) update(i);
for(int i=1;i<=m;i++)
{
int a,b,c;
citeste(a),citeste(b),citeste(c);
if(a==b) continue;
adj[a].pb(mp(b,c));
}
dijkstra();
printf("%d\n",cost[y]);
}