import std.stdio;
import std.ascii;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

struct S {
    int y, x;
    int time;
    string[] F;
    static const dy = [1,   1,  1, 
                       0,       0,
                       -1, -1, -1], 
                 dx = [-1,  0,  1,
                       -1,      1,
                       -1,  0,  1];
    S[] nextStates() {
        S[] Ret;
        int N = cast(int)F.length;
        foreach (i; 0 .. 8) {
            int ny = y + dy[i],
                nx = x + dx[i];
            if (ny < 0 || ny >= N) continue;
            if (nx < 0 || nx >= N) continue;
            if (F[ny][nx] == '#') continue;
            Ret ~= S(ny, nx, time + 1, next(F, ny, nx));
        }
        return Ret;
    }
    static string[] next(string[] F, int y, int x) {
        int N = cast(int)F.length;
        auto Ret = new char[][](N, N);
        foreach (i; 0 .. N) {
            foreach (j; 0 .. N) {
                int C = 0;
                if (i == y && j == x) {
                    Ret[i][j] = '.';
                    continue;
                }
                foreach (k; 0 .. 8) {
                    int py = i + dy[k],
                        px = j + dx[k];
                    if (py < 0 || py >= N) continue;
                    if (px < 0 || px >= N) continue;
                    if ((py == y && px == x) || F[py][px] == '#') C++;
                }
                if ( (F[i][j] == '#' && (C == 2 || C == 3)) ||
                     (F[i][j] == '.' && C == 3) ) {
                    Ret[i][j] = '#';
                } else {
                    Ret[i][j] = '.';
                }
            }
        }
        return cast(string[])Ret;
    }
}

void main() {
    int N;
    string[] F;
    int y, x;
    bool input() {
        scanf("%d\n", &N);
        if (N == 0) return false;
        F = new string[N];
        foreach (i; 0 .. N) F[i] = readln.chomp;
        foreach (i; 0 .. N) {
            foreach (j; 0 .. N) {
                if (F[i][j] == '@') {
                    y = i, x = j;
                }
            }
        }
        F = F.map!((l) => l.replace("@", ".")).array;
        return true;
    }
    static bool check(string[] F) {
        auto N = F.length;
        foreach (i; 0 .. N) {
            foreach (j; 0 .. N) {
                if (F[i][j] != '.') return false;
            }
        }
        return true;
    }
    string encode(S s) {
        return s.F.join("") ~ s.y.to!string ~ " " ~ s.x.to!string;
    }
    void solve() {
        DList!S Q;
        Q.insert(S(y, x, 0, F));
        int Ans = -1;
        bool[string] used;
        while (!Q.empty) {
            S s = Q.front; Q.removeFront;
            if (check(s.F)) {
                Ans = s.time;
                break;
            }
            foreach (t; s.nextStates) {
                auto k = encode(t);
                if (k in used) continue;
                used[k] = true;
                Q.insert(t);
            }
        }
        writeln(Ans);
    }
    while (input) solve;
}