import java.util.*;
public class Dijkstra模板 {
static int dis[] = new int[1005];
static boolean vis[] = new boolean[1005];
static int head[] = new int[1005]; // 存放链头
static edge[] e = new edge[1005];
static int len; // 边的个数
static int n, m; // n 顶点个数 m 边数
static void init() {
Arrays.fill(head, -1);
Arrays.fill(dis, 0x3f3f3f3f); // 赋值为负无穷
}
static void add(int u, int v, int w) {
e[len] = new edge(v, w, head[u]); // 前插法
head[u] = len++; // 将u指向新添加的边
}
// 无向边的添加
static void add2(int u, int v, int w) {
add(u, v, w);
add(v, u, w);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
init();
n = sc.nextInt();
m = sc.nextInt();
int u, v, w;
for (int i = 0; i < m; i++) {
u = sc.nextInt();
v = sc.nextInt();
w = sc.nextInt();
add2(u, v, w);
}
dijkstra1(1);
for (int i = 1; i <= n; i++) {
System.out.print(dis[i] + " ");
}
System.out.println();
System.out.println(dis[n]);
}
/*
* 利用优先级队列进行优化 O(vlgv + e)
*/
static void dijkstra1(int u) {
dis[u] = 0;
PriorityQueue<node> q = new PriorityQueue<node>();
q.add(new node(0, u));
while (!q.isEmpty()) {
u = q.poll().v;
//因为可能有重复点进去
if (vis[u]) continue;
vis[u] = true;
for (int j = head[u]; j != -1; j = e[j].next) {
int v = e[j].v;
int w = e[j].w;
if (!vis[v] && dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.add(new node(dis[v], v));
}
}
}
}
/*
* 不优化
*/
static void dijkstra2(int u) {
dis[u] = 0;
for (int i = 0; i < n; i++) { // 循环n遍 标记n个点
int mind = 1000000000, minj = -1;
for (int j = 1; j <= n; j++) { // 从n个点中找出dis最小的
if (!vis[j] && dis[j] < mind) {
mind = dis[j];
minj = j;
}
}
if (minj == -1) {
// 代表有点无法到达
return;
}
vis[minj] = true; // 将这个最小的点进行标记
for (int j = head[minj]; j != -1; j = e[j].next) {
int v = e[j].v;
int w = e[j].w;
if (!vis[v] && dis[v] > dis[minj] + w) {
dis[v] = dis[minj] + w;
}
}
}
}
}
class edge {
int v, w, next;
public edge(int v, int w, int next) {
this.v = v;
this.w = w;
this.next = next;
}
public edge() {
}
}
class node implements Comparable<node> {
int minDis, v;
public node(int minDis, int v) {
this.minDis = minDis;
this.v = v;
}
public int compareTo(node o) {
if (minDis == o.minDis) {
return (v - o.v); // 优先队列中 小的在头
}
return (minDis - o.minDis);
}
}