#include <cstdio>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
#define MAX 100
const int INF = (1<<30) - 1;
typedef pair<int,int> pii;
priority_queue< pii , vector<pii> , greater<pii> > q; //优先队列
int edges[MAX][MAX]; //邻接表
int n , m;
int d[MAX]; //路径长度
void init()
{
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
if(i == j)
edges[i][j] = 0;
else
edges[i][j] = INF;
}
}
}
void dijkstra(int v)
{
bool done[MAX];
for(int i = 0; i < n; ++i)
{
d[i] = (edges[v][i] == 0 ? 0 : INF);
}
memset(done,0,sizeof(done));
q.push(make_pair(d[v],v)); \\ v:起点
while(!q.empty())
{
pii u = q.top();
q.pop();
int x = u.second;
if(done[x]) continue;
done[x] = true;
for(int j = 0; j < n; ++j)
{
if(!done[j] && edges[x][j] < INF && d[x] + edges[x][j] < d[j])
{
d[j] = d[x] + edges[x][j];
q.push( make_pair(d[j],j) );
}
}
}
for(int i = 0; i < n; ++i)
{
cout << d[i] << endl;
}
}
int main()
{
int vi = 0;
int u , v , w;
cin >> n >> m;
init();
for(int i = 0; i < m; ++i) //无向图的输入
{
cin >> u >> v >> w;
edges[u][v] = edges[v][u] = w;
}
dijkstra(vi);
return 0;
}