#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
void dijkstra(const vector<vector<pair<long long,long long>>> &adj, long long start, vector<long long> &dist) {
long long n = adj.size();
vector<bool> processed(n, false);
dist.assign(n, 0);
priority_queue<pair<long long,long long>> pq;
dist[start] = LLONG_MAX;
pq.push({0, start});
while (!pq.empty()) {
long long a = pq.top().second;
pq.pop();
if (processed[a]) continue;
processed[a] = true;
for (auto [b, w] : adj[a]) {
if(dist[b] < min(dist[a],w)) {
dist[b] = min(w,dist[a]);
pq.push({dist[b], b});
}
}
}
}
void topological_sort(const vector<vector<long long>> &adj, vector<long long> &order) {
int n = adj.size();
vector<long long> indegree(n, 0);
for (int u = 0; u < n; u++) {
for (int v : adj[u]) {
indegree[v]++;
}
}
queue<int> q;
for (int i = 0; i < n; i++) {
if (indegree[i] == 0) q.push(i);
}
order.reserve(n);
while (!q.empty()) {
int u = q.front();
q.pop();
order.push_back(u);
for (int v : adj[u]) {
indegree[v]--;
if (indegree[v] == 0) q.push(v);
}
}
if ((int)order.size() != n) {
cout << "IMPOSSIBLE" << endl;
return ;
}
}
void task1(){
int n, q;
cin >> n >> q;
vector<ll> cells(n);
for(int i = 0; i < n; i++){
cin >> cells[i];
}
vector<ll> queries(n);
for(int i = 0; i < q; i++){
cin >> queries[i];
}
}
void task2(){
int n, m;
cin >> n >> m;
vector<vector<pair<long long,long long>>> adj(n);
vector<long long> dist;
for (long long i = 0; i < m; i++) {
long long a, b, w;
cin >> a >> b >> w;
a--; b--;
adj[a].push_back({b, w});
adj[b].push_back({a, w});
}
dijkstra(adj, 0, dist);
for (long long i = 1; i < n; i++) {
cout << dist[i] << " ";
}
}
int main() {
task2();
return 0;
}