#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define N 1005
vector<int> grub[N],grub2[N];
int cev[N][N];
int two[N];
int father[N],sze[N];
int dsu(int x){
if(father[x]==x)return x;
return father[x]=dsu(father[x]);
}
void kardes(int x,int y){
x=dsu(x);y=dsu(y);
if(x==y)return;
if(sze[x]<sze[y])swap(x,y);
sze[x]+=sze[y];
father[y]=x;
}
/*int father2[N],sze2[N];
int dsu2(int x){
if(father2[x]==x)return x;
return father2[x]=dsu2(father2[x]);
}
void kardes2(int x,int y){
x=dsu2(x);y=dsu2(y);
if(x==y)return;
if(sze2[x]<sze2[y])swap(x,y);
sze2[x]+=sze2[y];
father2[y]=x;
}
*/
void build(vector<vector<int>> _b);
int construct(vector<vector<int>> p) {
int n = p.size();
for(int i=0;i<=n;i++){
father[i]=i;
sze[i]=1;
//father2[i]=i;
//sze2[i]=1;
//two[i]=0;
grub[i].clear();
//grub2[i].clear();
}
for (int i = 0; i < n; i++) {
int iki=0,bir=0;
for(int j=0;j<n;j++){
cev[i][j]=0;
if(p[i][j])kardes(i,j);
//if(p[i][j]==2)iki++;
//if(p[i][j]==1)bir++;
}
//if(bir==1&&iki)two[i]=1;
}
/*for (int i = 0; i < n; i++) {
if(two[i]==0)continue;
for(int j=0;j<n;j++){
if(p[i][j]==2&&two[j])kardes2(i,j);
}
}*/
for (int i = 0; i < n; i++) {
for(int j=i+1;j<i;j++){
if(p[i][j]==0&&dsu(i)==dsu(j))return 0;//bağlantı kontrol
if(p[i][j]&&dsu(i)!=dsu(j))return 0;
}
grub[dsu(i)].pb(i);
//if(two[i])grub2[dsu2(i)].pb(i);
}
for(int k=0;k<n;k++){
int ok=0;
if(grub[k].size()<=1)continue;
vector<int> v=grub[k];
/*int bas=-1;
for(auto x:grub[k]){
if(two[x]){
bas=dsu2(x);
continue;
}
if(v.size()==0)
for(int i=0;i<n;i++){
if(p[x][i]==1)v.pb(i);
}
}
//cout<<bas<<endl;
//for(auto u:v)cout<<u<<" ";
//cout<<endl;
if(v.size()==0){
if(bas==-1)return 0;
int m=grub2[bas].size();
for(int i=0;i<m;i++){
cev[grub2[bas][i]][grub2[bas][((i-1+m)%m)]]=1;
cev[grub2[bas][((i-1+m)%m)]][grub2[bas][i]]=1;
cev[grub2[bas][i]][grub2[bas][((i+1+m)%m)]]=1;
cev[grub2[bas][((i+1+m)%m)]][grub2[bas][i]]=1;
}
continue;
}*/
int m=v.size();
int once=-1;
for(int i=0;i<m;i++){
if(once!=-1){
cev[once][v[i]]=1;
cev[v[i]][once]=1;
}
once=v[i];
}
/*if(once==-1)return 0;
if(bas!=-1){
int oncee=once;
int m=grub2[bas].size();
for(int i=0;i<m;i++){
cev[grub2[bas][i]][once]=1;
cev[once][grub2[bas][i]]=1;
once=grub2[bas][i];
if(i==m-1){
cev[grub2[bas][i]][oncee]=1;
cev[oncee][grub2[bas][i]]=1;
}
}
}*/
}
vector<vector<int>> answer;
for(int i=0;i<n;i++){
vector<int> row;
for(int j=0;j<n;j++){
//cout<<cev[i][j]<<" ";
row.pb(cev[i][j]);
}
//cout<<endl;
answer.pb(row);
}
build(answer);
return 1;
}
/*int n;
vector<vector<int>> p;
vector<vector<int>> b;
bool called = false;
static void check(bool cond, string message) {
if (!cond) {
printf("%s\n", message.c_str());
fclose(stdout);
exit(0);
}
}
void build(vector<vector<int>> _b) {
check(!called, "build is called more than once");
called = true;
check((int)_b.size() == n, "Invalid number of rows in b");
for (int i = 0; i < n; i++) {
check((int)_b[i].size() == n, "Invalid number of columns in b");
}
b = _b;
}
int main() {
assert(scanf("%d", &n) == 1);
p.resize(n);
for (int i = 0; i < n; i++) {
p[i].resize(n);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
assert(scanf("%d", &p[i][j]) == 1);
}
}
fclose(stdin);
int possible = construct(p);
check(possible == 0 || possible == 1, "Invalid return value of construct");
if (possible == 1) {
check(called, "construct returned 1 without calling build");
} else {
check(!called, "construct called build but returned 0");
}
printf("%d\n", possible);
if (possible == 1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j) {
printf(" ");
}
printf("%d", b[i][j]);
}
printf("\n");
}
}
fclose(stdout);
}*/