#include<bits/stdc++.h>
#include<vector>
using namespace std;
int lj[1010][1010];//鄰接矩陣
//可以換成鏈式前向星之類的巴拉巴拉,這裡用鄰接矩陣演示比較清楚
int n,m;
int flyd[1001][1001];
int main(){
cin>>n>>m;
for (int i=1; i<=m; i++){
int u,v,w;
cin>>u>>v>>w;
lj[u][v]=w;
}
//輸入邊,權值
for (int i=1; i<=n; i++){//初始化
for (int j=1; j<=n; j++){
if (i==j) flyd[i][j]=0;
else if (lj[i][j]) flyd[i][j]=lj[i][j];
else{
flyd[i][j]=1000000000;
}
}
}
/*
從小到大,經過新的節點,可能使路徑更短
時間複雜度較高
*/
for (int k=1; k<=n; k++){//每一個新節點進行更新,找到代價最小的路
for (int i=1; i<=n; i++){
for (int j=1; j<=n; j++){
flyd[i][j]=min(
flyd[i][j],
flyd[i][k]+flyd[k][j]
);
}
}
}
for (int i=1; i<=n; i++){
for (int j=1; j<=n; j++){
cout<<flyd[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
/*
5 6
1 2 1
1 3 2
1 5 1
2 4 5
3 4 3
4 5 4
*/