//Roy Floyd
//doar lungimile drumuriloe
//O(n^3)
//100p infoarena
program saddasdasdasd;
const infinit=maxint;
type mat=array[1..100,1..100]of longint;
vect=array[0..100]of longint;
var d,tata:mat;
intrare,iesire:array[1..1 shl 17]of char;
i,j,n,m,start,finish:longint;
f,g:text;
procedure initializare;
var i,j,x,y,cost:longint;
begin
readln(f,n,m,start,finish);
for i:=1 to n do
for j:=1 to n do begin
if i<>j then d[i,j]:=infinit
else d[i,i]:=0;
tata[i,j]:=i; tata[j,i]:=0;//?
end;
for i:=1 to m do begin
readln(f,x,y,cost);
d[x,y]:=cost; d[y,x]:=cost;
tata[x,y]:=x; tata[y,x]:=y;
end;
end;
procedure drumuri(var d:mat);
var i,j,k:integer;
begin
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
if(d[i,k]<>infinit)and(d[k,j]<>infinit)then//ca sa pot obtine mai putin
if i<>j then //aici ramane 0 oricum
if (d[i,k]<>0)and(d[k,j]<>0) then //pt costuri strict mai mari ca 0
if (d[i,j]>d[i,k]+d[k,j])or(d[i,j]=0) then //daca ma ajuta
begin
d[i,j]:=d[i,k]+d[k,j];
tata[i,j]:=tata[k,j];
end;
end;
procedure afisare(x,y:integer);
var dr:vect; lg,i:integer;
begin
dr[1]:=y;lg:=1;
while dr[lg]<>x do
begin
inc(lg);
dr[lg]:=tata[y,x];
y:=tata[y,x];
end;
for i:=lg downto 1 do write(g,dr[i]:3);
writeln(g);
end;
begin
assign(f,'royfloyd.in'); reset(f); settextbuf(f,intrare);
assign(g,'royfloyd.out'); rewrite(g); settextbuf(g,iesire);
initializare;
drumuri(d);
//afisare(start,finish);
for i:=1 to n do
begin
for j:=1 to n do write(g,tata[i,j],' ');
writeln(g);;
end;
close(f);close(g);
end.