#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define MAXX 1000000
using namespace std;
int n,m,s,t,cont,x[1010][1010];
int first[MAXX],next1[MAXX],u[MAXX],v[MAXX],w[MAXX],dis[MAXX],vis[MAXX];
int buildmap(int a,int b,int c)
{
u[cont]=a,v[cont]=b,w[cont]=c;
next1[cont]=first[a];
first[a]=cont++;
}
struct zp
{
int a;//记录点
int b;//记录从起点到该点的最短路
bool friend operator < (zp &x,zp &y)
{
return x.b>y.b;//小优先
}
};
void Dijkstar()//Dijkstar优先队列优化
{
priority_queue<zp>q;
memset(dis,0x3f3f3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
zp p;
p.a=s;
p.b=0;
q.push(p);
while(!q.empty())
{
p=q.front();
q.pop();
int k=first[p.a];
if(vis[p.a]) continue;
vis[p.a]=1;
while(k!=-1)
{
if(dis[v[k]]>dis[u[k]]+w[k])
{
dis[v[k]]=dis[u[k]]+w[k];
if(!vis[v[k]])
{
p.a=v[k];
p.b=dis[v[k]];
q.push(p);
}
}
k=next1[k];
}
}
}
void Dijkstar1()//普通Dijkstar
{
memset(dis,0x3f3f3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
for(int i=1;i<=n;i++)
dis[i]=x[s][i];
vis[s]=1;
for(int i=1;i<=n-1;i++)
{
int Min=0x3f3f3f3f3f3f3f;
int flag;
for(int i=1;i<=n;i++)
if(!vis[i]&&dis[i]<Min)
{
Min=dis[i];
flag=i;
}
vis[flag]=1;
for(int i=1;i<=n;i++)
{
if(dis[i]>dis[flag]+x[flag][i])
dis[i]=dis[flag]+x[flag][i];
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&s,&t))//点,边,起点,终点;
{
int a,b,c;
//cont=1;
//memset(first,-1,sizeof(first));
// for(int i=0;i<m;i++)//临接表存图,用于优先队列优化,不可判重边
// {
// scanf("%d%d%d",&a,&b,&c);
// buildmap(a,b,c);
// buildmap(b,a,c);
// }
memset(x,0x3f3f3f,sizeof(x));
for(int i=0;i<m;i++)//临接矩阵存图,普通可判重边
{
scanf("%d%d%d",&a,&b,&c);
if(x[a][b]>c)//判重边
x[a][b]=x[b][a]=c;
}
Dijkstar1();
//Dijkstar();
printf("%d\n",dis[t]);
}
}