### constant

INF = 1 << 30

DXYS = [
  [ 1, 0], [1, -1], [0, -1], [-1, -1],
  [-1, 0], [-1, 1], [0,  1], [ 1,  1]
]

### subroutines

def tostr(n, bits, pos)
  str = ''
  for k  in (0...(n * n))
    if k == pos
      str += '@'
    else
      str += (bits & (1 << k)) == 0 ? '.' : '#'
    end
    str += "\n" if (k + 1) % n == 0
  end
  str
end

def infection(nn, bits, adjs)
  return $icache[bits] if $icache[bits]

  ibits = bits

  for pos in (0...nn)
    c = 0
    adjs[pos].each{|apos| c += ((bits >> apos) & 1)}

    b = 1 << pos
    if (bits & b) == 0
      ibits |= b if c == 3
    else
      ibits &= ~b if c != 2 && c != 3
    end
  end

  $icache[bits] = ibits
end

### main

loop do
  n = gets.to_i
  break if n == 0

  nn = n * n

  sbits = 0
  spos = 0
  for y in (0...n)
    line = gets.strip
    for x in (0...n)
      pos = y * n + x
      case line[x]
      when '#'
        sbits |= (1 << pos)
      when '@'
        spos = pos
      end
    end
  end
  #p sbits.to_s(2)
  #p spos

  adjs = []
  for y0 in (0...n)
    for x0 in (0...n)
      adj = []
      DXYS.each do |dx, dy|
        x = x0 + dx
        y = y0 + dy
        if x >= 0 && x < n && y >= 0 && y < n
          adj << (y * n + x)
        end
      end
      adjs << adj
    end
  end
  #p adjs

  $icache = {}
  
  dists = nn.times.map{Hash.new{INF}}
  dists[spos][sbits] = 0
  q = [[spos, sbits]]
  min_d = INF
  
  while ! q.empty?
    upos, ubits = q.shift
    ud = dists[upos][ubits]
    #puts tostr(n, ubits, upos); puts
    
    if ubits == 0
      min_d = ud
      break
    end

    nvd = ud + 1

    for vpos in adjs[upos]
      #p [upos, vpos]
      vb = (1 << vpos)
      if (ubits & vb) == 0
        vbits = (infection(nn, (ubits | vb), adjs) & ~vb)
        #p [ubits.to_s(2), vbits.to_s(2)]
        if dists[vpos][vbits] >= nvd
          dists[vpos][vbits] = nvd
          q << [vpos, vbits]
        end
      end
    end
  end

  #p $icache
  #p dists
  puts (min_d >= INF ? -1 : min_d)
end