#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=9901;
const int INF=1000000;
#define forn(i,a,b) for(int i=a;i<b;i++)
const int N=1000000,M=1000000;
int head[N],ver[M],edge[M],nex[M],d[M];
int n,m;int top=0;
bool v[N];
priority_queue<pair<int,int>>q;
/*
* Dijkstra算法核心是:
* 首先该算法是基于贪心策略
* 找到未标记结点中 d[x]最小的结点x 然后标记结点x
*如果其d[y]>d[x]+z 更新答案 并重复上一步 直到所有节点标记完
*/
void add(int x,int y,int z){
ver[++top]=y;edge[top]=z;
nex[top]=head[x];
head[x]=top;
}
void Dijkstra(){
memset(d,0x3f,sizeof d);
memset(v,0,sizeof v);
d[1]=0;
q.push(make_pair(0,1));
while(q.size()){
int x=q.top().second;q.pop();
if(v[x])
continue;
v[x]=1;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
int z=edge[i];
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
Dijkstra();
for(int i=1;i<N;i++)
cout<<d[i]<<endl;
return 0;
}