//题意:这是一道图算法题,就是单源最短路径问题R条边,N个顶点,求出次短的路径长度
//思路:求解最短路径的方法基础下,可以联想到次短路径是在最短路径下分2种情况得到
//1:要么是到某个顶点u的最短路径加上u->v的边
//2:要么是到某个顶点u的次短距离在加上u->v的边
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define MAX_N 5005
#define INF 1<<29
struct edge{
int to;
int cost;
};
vector<edge>G[MAX_N];
typedef pair<int,int>P;//first最短路径和second顶点号
void addedge(int src,int dest,int cost){
edge e = {dest-1,cost};
edge e2 ={src-1,cost};
G[src-1].push_back(e);
G[dest-1].push_back(e2);
}
int main(){
int N,R;
scanf("%d %d",&N,&R);
for (int i=0;i<R;++i)
{
int src,dest,cost;
scanf("%d %d %d",&src,&dest,&cost);
addedge(src,dest,cost);
}
int dist[MAX_N];//最短路径
int dist2[MAX_N];//次短路径
//键值比较是第一个Key值
priority_queue<P,vector<P>,greater<P> >que;
fill(dist,dist+N,INF);
fill(dist2,dist2+N,INF);
dist[0] = 0;
que.push(P(0,0));
while(!que.empty()){
P p = que.top();que.pop();
int v = p.second,d =p.first;
if (dist2[v]<d)
continue;
for (int i=0;i<G[v].size();++i)
{
edge&e = G[v][i];
int d2 = d + e.cost;
if (dist[e.to]>d2)
{
swap(dist[e.to],d2);
que.push(P(dist[e.to],e.to));
}
if (dist2[e.to]>d2&&dist[e.to]<d2)//次短的
{
dist2[e.to] = d2;
que.push(P(dist2[e.to],e.to));
}
}
}
printf("%d\n",dist2[N-1]);
return 0;
}