含负权时,dijks不可用
//无向图,边数要乘2
//friend bool 返回的 相反
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e4;
int n,m,cnt,s;
int head[105],dis[105],vis[105];
struct edge{
int to,dis,nex;
}e[2*maxn+5];//无向图,边数要乘2
void adde(int u,int v,int w){
e[++cnt].to=v;
e[cnt].dis=w;
e[cnt].nex=head[u];
head[u]=cnt;
}
struct node{
int id,dis;
friend bool operator < (node a,node b){
return a.dis>b.dis;
//friend bool 返回的 相反
}
};
void djs(){
priority_queue<node>q;
s=1;dis[s]=0;
q.push(node{s,0});
//这里第一个vis不用置1,因为while里vis为1就直接跳过了,只有vis为0,才能遍历s能到的点,更新这些点的最短路径
while(!q.empty()){
node cur=q.top();q.pop();
int u=cur.id;
if(!vis[u]){
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].nex){
int v=e[i].to;
//dis[u]不是i,i是下标,u才是点
if(dis[v]>dis[u]+e[i].dis){
dis[v]=dis[u]+e[i].dis;
q.push(node{v,dis[v]});
}
}
}
}
}
int main(){
int a,b,c;
while(cin>>n>>m){
if(n==0&&m==0) break;
for(int i=0;i<=n;i++){
vis[i]=0;dis[i]=inf;head[i]=-1;
}
cnt=0;//多组数据建边前cnt清0
while(m--){
scanf("%d%d%d",&a,&b,&c);
adde(a,b,c);
adde(b,a,c);
}
djs();
printf("%d\n",dis[n]);
}
}