#include <fstream>
using namespace std;
// Se da o matrice n x n care memoreaza 0 si 1
// 1 - obstacol
// 0 - liber
// (1, 1) -> (n, n) pe drum minim
struct coord
{
int x, y;
};
coord q[100001];
int a[101][101], n, d[101][101];
// d(i,j) = dr minim de la (1,1) la (i,j)
void Citire()
{
int i, j;
ifstream fin ("lee.in");
fin >> n;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
fin >> a[i][j];
fin.close();
}
void Bordare()
{
int i;
for (i = 0; i <= n + 1; i++)
a[0][i] = a[i][0] =
a[i][n+1] = a[n+1][i] = 1;
}
void Lee()
{
coord w, w1;
int st, dr;
int cost;
st = dr = 0;
q[0].x = 1;
q[0].y = 1;
d[1][1] = 1;
while (st <= dr) // am elemente in q
{
w = q[st];
cost = d[w.x][w.y];
st++;
// vecin nord
w1.x = w.x - 1;
w1.y = w.y;
if (a[w1.x][w1.y] == 0)
if (d[w1.x][w1.y] == 0 || d[w1.x][w1.y] > cost + 1)
{
d[w1.x][w1.y] = cost + 1;
dr++;
q[dr] = w1;
}
// vecin sud
w1.x = w.x + 1;
w1.y = w.y;
if (a[w1.x][w1.y] == 0)
if (d[w1.x][w1.y] == 0 || d[w1.x][w1.y] > cost + 1)
{
d[w1.x][w1.y] = cost + 1;
dr++;
q[dr] = w1;
}
// vecin est
w1.x = w.x;
w1.y = w.y + 1;
if (a[w1.x][w1.y] == 0)
if (d[w1.x][w1.y] == 0 || d[w1.x][w1.y] > cost + 1)
{
d[w1.x][w1.y] = cost + 1;
dr++;
q[dr] = w1;
}
// vecin vest
w1.x = w.x;
w1.y = w.y - 1;
if (a[w1.x][w1.y] == 0)
if (d[w1.x][w1.y] == 0 || d[w1.x][w1.y] > cost + 1)
{
d[w1.x][w1.y] = cost + 1;
dr++;
q[dr] = w1;
}
}
}
void Afisare()
{
int i, j;
ofstream fout("lee.out");
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
fout << d[i][j] << " ";
fout << "\n";
}
}
int main()
{
Citire();
Bordare();
Lee();
Afisare();
return 0;
}