#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
#define MAXV 500
#define inf 0x0fffffff
int V,E;
struct edge
{
int to,cost;
edge(int a,int b)
{
to=a;
cost=b;
}
};
vector<edge>G[MAXV];
typedef pair<int,int>P; //最短距离 编号
int d[MAXV];
int prev[MAXV];
class cmp
{
public:
bool operator()(P a,P b)
{
return a.first>b.first;
}
};
void dijsktra(int s)
{
priority_queue<P,vector<P>,cmp>que;
memset(prev,-1,sizeof(prev));
int i;
for(i=0;i<MAXV;i++)
d[i]=inf;
d[s]=0;
que.push(P(0,s));
while(!que.empty())
{
P p=que.top();
que.pop();
int v=p.second;
if(p.first>d[v])
continue;
for(i=0;i<G[v].size();i++)
{
edge e=G[v][i];
if(d[e.to]>d[v]+e.cost)
{
d[e.to]=d[v]+e.cost;
prev[e.to]=v;
que.push(P(d[e.to],e.to));
}
}
}
}
void path(int t)
{
vector<int>path;
while(t!=-1)
{
path.push_back(t);
t=prev[t];
}
reverse(path.begin(),path.end());
vector<int>::iterator ite;
for(ite=path.begin();ite!=path.end();ite++)
cout<<*ite<<" ";
cout<<endl;
}
int main()
{
freopen("C:\\1.txt","r",stdin);
cin>>V>>E;
int i;
for(i=0;i<E;i++)
{
int f,t,c;
cin>>f>>t>>c;
G[f].push_back(edge(t,c));
G[t].push_back(edge(f,c));
}
vector<edge>::iterator ite;
for(i=0;i<V;i++)
for(ite=G[i].begin();ite!=G[i].end();ite++)
cout<<i<<" "<<ite->to<<" "<<ite->cost<<endl;
dijsktra(0);
for(i=0;i<V;i++)
cout<<d[i]<<endl;
path(6);
return 0;
}