#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,r;
int h[5005],to[10005],ne[10005],w[10005],idx;
bool vis[5005];
int g[5005],dis[5005];
int k;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >heap;
struct node
{
int step,x;
bool operator<(node y)const
{
return this->step+dis[this->x]>y.step+dis[y.x];
}
};
priority_queue<node>q;
void add(int x,int y,int z)
{
to[idx]=y;
w[idx]=z;
ne[idx]=h[x];
h[x]=idx++;
}
void DijkstraPhoenix(void)
{
dis[n]=0;
heap.push(make_pair(dis[n],n));
while(!heap.empty())
{
int y=heap.top().second;
heap.pop();
if(vis[y])continue;
vis[y]=true;
for(int i=h[y];i!=-1;i=ne[i])
{
int z=to[i];
if(dis[y]+w[i]<dis[z])
{
dis[z]=dis[y]+w[i];
heap.push(make_pair(dis[z],z));
}
}
}
}
void Astar(void)
{
q.push(node{0,1});
while(!q.empty())
{
node x=q.top();
q.pop();
int f=x.step,s=x.x;
if(s==n)
{
if(k==1)
{
cout<<f;
exit(0);
}
else k++;
}
for(int i=h[s];i!=-1;i=ne[i])
{
int j=to[i];
q.push(node{f+w[i],j});
}
}
}
signed main(void)
{
memset(h,-1,sizeof(h));
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
cin>>n>>r;
for(int i=1;i<=r;i++)
{
int u,v,e;
cin>>u>>v>>e;
add(u,v,e);
add(v,u,e);
}
DijkstraPhoenix();
Astar();
return 0;
}