from collections import deque
N = int(input())
dap = []
base_pan = []
visit_pan = []
door = []
for i in range(N):
temp_input = input()
temp_base_pan = []
temp_visit_pan = []
for j in range(N):
if temp_input[j] == "#":
door.append([i, j])
temp_base_pan.append(temp_input[j])
temp_visit_pan.append([N * N] * 4)
base_pan.append(temp_base_pan)
visit_pan.append(temp_visit_pan)
move_1 = [-1, 1, 0, 0]
move_2 = [0, 0, -1, 1]
def move(org_x, org_y, org_direction, mirror):
temp_x = org_x + move_1[org_direction]
temp_y = org_y + move_2[org_direction]
if (door[1][0] == org_x) & (door[1][1] == org_y):
dap.append(mirror)
elif (temp_x < 0) | (temp_y < 0) | (temp_x >= N) | (temp_y >= N):
return
elif base_pan[temp_x][temp_y] == "*":
return
elif (visit_pan[temp_x][temp_y][org_direction] <= mirror) & (
base_pan[temp_x][temp_y] != "#"
):
return
else:
que.append([[temp_x, temp_y], org_direction, mirror])
visit_pan[temp_x][temp_y][org_direction] = mirror
if base_pan[temp_x][temp_y] == "!":
if (org_direction == 0) | (org_direction == 1):
que.append([[temp_x, temp_y], 2, mirror + 1])
que.append([[temp_x, temp_y], 3, mirror + 1])
else:
que.append([[temp_x, temp_y], 0, mirror + 1])
que.append([[temp_x, temp_y], 1, mirror + 1])
def bfs(que):
while len(que) > 0:
location = que.popleft()
org_x = location[0][0]
org_y = location[0][1]
org_direction = location[1]
mirror = location[2]
if org_direction == 99:
for i in range(4):
move(org_x, org_y, i, mirror)
else:
move(org_x, org_y, org_direction, mirror)
que = deque()
que.append([door[0], 99, 0])
bfs(que)
print(min(dap))