#include <iostream>
#include <cstring>
#define MAXI 105
#define INF 0x3f3f3f
using namespace std;
int a[MAXI][MAXI]; //无向图
int n,m; //顶点数和边数
int prev[MAXI][MAXI]; //路径
int f[MAXI][MAXI]; //最短路径
void Floyd()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
f[i][j]=a[i][j];
prev[i][j]=j;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(f[i][j]>f[i][k]+f[k][j])
{
f[i][j]=f[i][k]+f[k][j];
prev[i][j]=prev[i][k];
}
}
void creat()
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=INF;
for(int i=1;i<=n;i++)
a[i][i]=0;
}
int main()
{
int w,u,v;
cin>>n>>m;
creat();
for(int i=0;i<m;i++)
{
cin>>u>>v>>w;
a[u][v]=w;
a[v][u]=w;
}
Floyd();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<f[i][j]<<" ";
cout<<endl;
}
cout<<endl;
for(int i=1;i<n;i++)
{
for(int j=1;j<n;j++)
cout<<prev[i][j]<<" ";
cout<<endl;
}
int ff,en;
cin>>ff>>en;
while(ff!=en)
{
cout<<ff<<"->";
ff=prev[ff][en];
}
cout<<en<<endl;
return 0;
}
/*
7 12
1 2 7
1 3 9
1 6 14
2 3 10
2 4 15
3 4 11
3 6 2
4 5 6
5 6 9
7 4 7
7 5 5
7 6 3
*/