/*
  Copyright 2011 Marek "p2004a" Rusinowski
  Dijkstra algorithm
*/
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>

#define MAXN 1000000
#define INF 0x7FFFFFF0

std::vector<std::pair<int, int> > edges[MAXN];
int d[MAXN], n, m;

struct cmp {
  bool operator() (int a, int b) {
    if (d[a] < d[b]) return true;
    if (d[a] > d[b]) return false;
    return a < b;
  }
};

void dijkstra(int v) {
  std::set<int, cmp> q;
  std::fill(d, d + n, INF);
  q.insert(v);
  d[v] = 0;
  while (!q.empty()) {
    int v = *(q.begin());
    q.erase(q.begin());
    for (unsigned i = 0; i < edges[v].size(); ++i) {
      if (d[v] + edges[v][i].second < d[edges[v][i].first]) {
        q.erase(edges[v][i].first);
        d[edges[v][i].first] = d[v] + edges[v][i].second;
        q.insert(edges[v][i].first);
      }
    }
  }
}

int main() {
  int a, b, c;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    edges[--a].push_back(std::make_pair(--b, c));
    edges[b].push_back(std::make_pair(a, c));
  }
  dijkstra(0);
  for (int i = 0; i < n; ++i) {
    printf("%d ", d[i]);
  }
  printf("\n");
  return 0;
}
