import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
public class baekjoon_11043 {
static int N;
static int[][] graph;
static int[][] dp;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
graph = new int[N][N];
dp = new int[N][N];
for (int i = 0; i < N; i++) {
Arrays.fill(dp[i], Integer.MAX_VALUE);
String[] inputs = br.readLine().split(" ");
for (int j = 0; j < N; j++) {
graph[i][j] = Integer.parseInt(inputs[j]);
if (graph[i][j] != 0) {
dp[i][j] = 1;
}
}
}
floyd();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (dp[i][j] != Integer.MAX_VALUE) {
System.out.print(1 + " ");
} else {
System.out.print(0 + " ");
}
}
System.out.println();
}
}
private static void floyd() {
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (dp[i][k] == Integer.MAX_VALUE || dp[k][j] == Integer.MAX_VALUE) {
continue;
}
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
}
}
}
}
}
플로이드 와샬을 이용하면, 비용이 MAX_VALUE가 아니면 비용을 많이 들여서라도 갈 수 있다는 곳이라는 것을 알 수 있다.