#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
void bfs(int node);
// 인접 리스트를 위한 벡터를 만든다.
vector<int> v[101];
// 방문체크를 위한 배열
bool visited[101];
// 결과출력을 위한 배열
int result[101][101];
// 배열크기를 위한 N과 인풋값을 받을 input 변수
int N, input;
// 메인함수 시작부
int main() {
// N입력
cin >> N;
// 배열값을 입력받는다.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> input;
// 벡터배열 저장해준다.
// 사실 백터로 표현했지만 배열에 받는것과 같은 느낌
v[i].push_back(input);
}
}
// 0 ~ N-1까지 탐색해준다.
for(int i=0;i<N;i++){
bfs(i);
}
// 결과값 출력 부
for(int i=0;i<N;i++){
for(int j=0;j<N-1;j++){
cout << result[i][j] << " ";
}
// 마지막 값 후에 공백을 없애기 위해 사용
cout << result[i][N-1];
cout << '\n';
}
}
// 인접리스트에 저장된 값을 토대로 bfs를 사용해 문제를 풀기
void bfs(int node){
// 큐 생성
queue<int> q;
// 큐에 인덱스값을 넣어준다 (0 ~ N-1)
q.push(node);
// 다음 노드를 위해 방문체크를 false로 초기화 해준다.
memset(visited, false, sizeof(visited));
// 큐가 빌때까지 반복
while(!q.empty()){
//기 현재 큐에 저장되어 있는 값을 저장
int now = q.front();
// 방문체크
visited[now] = true;
// 큐에서 꺼내기
q.pop();
// 해당 노드의 각 간선 유무 확인
for(int i=0;i<N;i++){
// 간선이 있다는 것을 표현
if(v[now][i] == 1){
// 간선이 있으면 결과 배열에 1을 저장
result[node][i] = 1;
// 만약 방문한 간선이 아니라면 큐에 넣어준다.
if(!visited[i]) q.push(i);
}
}
}
}