#include<iostream>
#include<cstdio>
#include<deque>
#include<cstring>
using namespace std;
struct node
{
int to,from,dis,next;
};
node edge[400009];
int head[100009];
int flag[100009];
int dis[100009];
deque <int> q;
int num=1;
int m,n,p1,p2,p3;
void add(int from,int to,int dis)
{
edge[num].from=from;
edge[num].to=to;
edge[num].dis=dis;
edge[num].next=head[from];
head[from]=num;
num++;
}
int p(int st,int en)
{
memset(flag,0,sizeof(flag));
for(int i=1;i<=n;i++)
dis[i]=0x7fffffff/3;
int sum=0;
int cmt=1;
dis[st]=0;
q.push_front(st);
flag[st]=1;
while(q.empty()==0)
{
int u;
while(q.empty()==0)
{
if(dis[q.front()]*cmt<=sum)
{
cmt--;
u=q.front();
sum-=dis[u];
q.pop_front();
break;
}
else
{
q.push_back(q.front());
q.pop_front();
}
}
flag[u]=0;
for(int i=head[u];i!=0;i=edge[i].next)
{
if(dis[edge[i].to]>dis[u]+edge[i].dis)
{
dis[edge[i].to]=dis[u]+edge[i].dis;
if(flag[edge[i].to]==0)
{
flag[edge[i].to]=1;
cmt++;
sum+=dis[edge[i].to];
if(q.empty()==1||dis[edge[i].to]<dis[q.front()])
q.push_front(edge[i].to);
else q.push_back(edge[i].to);
}
}
}
}
return dis[en];
}
int main()
{
scanf("%d%d%d%d%d",&m,&n,&p1,&p2,&p3);
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
printf("%d",min(p(p1,p2),p(p1,p3))+p(p2,p3));
return 0;
}