#include"iostream"
#include"stdio.h"
#include"vector"
#include"functional"
#include"string"
#include"cstring"
#include"algorithm"
#include"queue"
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int maxn=2000+20;
const int INF=100000000;
struct edge
{
int from,to,dist;
edge(int u,int v,int w){from=u;to=v;dist=w;}
edge(){}
};
struct dijkstra
{
int n,m;
vector<int>g[maxn];
vector<edge>edges;
int visit[maxn];
int pre[maxn];
int road[maxn];
int d[maxn];
void get_path(int s,int e,vector<int>& path){
int pos = e;
while(1){
path.push_back(pos+1);
if(pos == s)
break;
pos = pre[pos];
}
}
void init(int n){this->n=n;for(int i=0;i<n;i++)g[i].clear();edges.clear();}
void add_edge(int u,int v,int w){edges.push_back(edge(u,v,w));int m=edges.size();g[u].push_back(m-1);}
void djk(int s)
{
priority_queue<pii,vector<pii>,greater<pii> >Q;
memset(visit,0,sizeof(visit));
for(int i=0;i<n;i++) d[i]=0;
d[s]=INF;
Q.push(make_pair(d[s],s));
visit[s]=1;
while(!Q.empty())
{
pii x=Q.top();Q.pop();
int u=x.second;
visit[u]=0;
for(int i=0;i<g[u].size();i++)
{
edge& e=edges[g[u][i]];
if(d[e.to]<min(e.dist,d[e.from]))
{
d[e.to]=min(e.dist,d[e.from]);
if(!visit[e.to])
{
Q.push(make_pair(d[e.to],e.to));
visit[e.to]=1;
}
}
}
}
}
};
int main()
{
//freopen("b.in","r",stdin);
//freopen("b.out","w",stdout);
int n;
int first=1;
while(scanf("%d",&n)==1)
{
int u,v,w;
dijkstra a;
a.init(n);
while(scanf("%d%d%d",&u,&v,&w)==3&&(u+v+w))
{
u--;v--;
a.add_edge(u,v,w);
}
a.djk(0);
for(int i=1;i<n;i++)
cout<<a.d[i]<<endl;
}
return 0;
}
/*
Accepted, time = 231 ms, mem = 824 KiB, score = 100 SFPA
*/
#include"iostream"
#include"stdio.h"
#include"vector"
#include"functional"
#include"string"
#include"cstring"
#include"algorithm"
#include"queue"
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int maxn=2000+20;
const int INF=100000000;
struct edge
{
int from,to,dist;
edge(int u,int v,int w){from=u;to=v;dist=w;}
edge(){}
};
struct dijkstra
{
int n,m;
vector<int>g[maxn];
vector<edge>edges;
int visit[maxn];
int pre[maxn];
int road[maxn];
int d[maxn];
void get_path(int s,int e,vector<int>& path){
int pos = e;
while(1){
path.push_back(pos+1);
if(pos == s)
break;
pos = pre[pos];
}
}
void init(int n){this->n=n;for(int i=0;i<n;i++)g[i].clear();edges.clear();}
void add_edge(int u,int v,int w){edges.push_back(edge(u,v,w));int m=edges.size();g[u].push_back(m-1);}
void djk(int s)
{
queue<pii>Q;
memset(visit,0,sizeof(visit));
for(int i=0;i<n;i++) d[i]=0;
d[s]=INF; //源点设为INF与他邻接的点才能取到值
Q.push(make_pair(d[s],s));
visit[s]=1;
while(!Q.empty())
{
pii x=Q.front();Q.pop();
int u=x.second;
visit[u]=0;
for(int i=0;i<g[u].size();i++)
{
edge& e=edges[g[u][i]];
if(d[e.to]<min(e.dist,d[e.from])) //d[j]=max(d[j],min(d[i],w[i][j])) 然后不断的做这个更新 直到无法继续更新
{
d[e.to]=min(e.dist,d[e.from]);
if(!visit[e.to])
{
Q.push(make_pair(d[e.to],e.to));
visit[e.to]=1;
}
}
}
}
}
};
int main()
{
//freopen("b.in","r",stdin);
//freopen("b.out","w",stdout);
int n;
int first=1;
while(scanf("%d",&n)==1)
{
int u,v,w;
dijkstra a;
a.init(n);
while(scanf("%d%d%d",&u,&v,&w)==3&&(u+v+w))
{
u--;v--;
a.add_edge(u,v,w);
}
a.djk(0);
for(int i=1;i<n;i++)
cout<<a.d[i]<<endl;
}
return 0;
}