#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std;
#define MAX 10
#define INF 0;
typedef int E;
typedef struct GraphMartix{
int vex,edge;
int marixWeight[MAX][MAX];
E data[MAX];
}*Graph;
Graph Create(int v){
Graph g= (Graph)malloc(sizeof(GraphMartix));
g->edge=g->vex=0;
memset(g->marixWeight,0,sizeof(g->marixWeight));
return g;
}
void addVex(Graph g,E v){
g->data[g->vex++]=v;
}
int getIndexByElem(Graph g,E v){
int i =0;
while(g){
if(g->data[i]==v)
return i;
i++;
}
return -1;
}
void addEdge(Graph g,E v1,E v2,int w){
int a=getIndexByElem(g,v1);
int b=getIndexByElem(g,v2);
g->marixWeight[v1-1][v2-1]=w;
g->marixWeight[v2-1][v1-1]=w;
g->edge++;
}
void printMarix(Graph g){
for(int i =0;i<g->vex;i++)
if(g->marixWeight[0][i]!=0)
{
cout<<g->marixWeight[0][i];
if(i<g->vex-1) cout<<" ";
}
cout<<endl;
}
void Fluid(Graph g){
for(int i =0 ;i <g->vex;i++)
for(int j=0;j<g->vex;j++)
for(int k=0;k<g->vex;k++)
{
if(g->marixWeight[j][i]!=0&&g->marixWeight[i][k]!=0&&j!=k)
{
int newDistance=g->marixWeight[j][i]+g->marixWeight[i][k];
if (newDistance < g->marixWeight[j][k] || g->marixWeight[j][k] == 0)
g->marixWeight[j][k] = newDistance;
}
}
printMarix(g);
}
int main(){
Graph graph = Create(4);
int n;
cin>>n;
for (int c =1;c<=n;++c)
addVex(graph,c);
int a,b,w;
while(cin>>a>>b>>w){
addEdge(graph,a,b,w);
}
//printMarix(graph);
Fluid(graph);
}