Alice lives on a flat planet that can be modeled as a square grid of size $n \times n$, with rows and columns enumerated from $1$ to $n$. We represent the cell at the intersection of row $r$ and column $c$ with ordered pair $(r, c)$. Each cell in the grid is either land or water.

 [Image] An example planet with $n = 5$. It also appears in the first sample test. 

Alice resides in land cell $(r_1, c_1)$. She wishes to travel to land cell $(r_2, c_2)$. At any moment, she may move to one of the cells adjacent to where she is—in one of the four directions (i.e., up, down, left, or right).

Unfortunately, Alice cannot swim, and there is no viable transportation means other than by foot (i.e., she can walk only on land). As a result, Alice's trip may be impossible.

To help Alice, you plan to create at most one tunnel between some two land cells. The tunnel will allow Alice to freely travel between the two endpoints. Indeed, creating a tunnel is a lot of effort: the cost of creating a tunnel between cells $(r_s, c_s)$ and $(r_t, c_t)$ is $(r_s-r_t)^2 + (c_s-c_t)^2$.

For now, your task is to find the minimum possible cost of creating at most one tunnel so that Alice could travel from $(r_1, c_1)$ to $(r_2, c_2)$. If no tunnel needs to be created, the cost is $0$.


-----Input-----

The first line contains one integer $n$ ($1 \leq n \leq 50$) — the width of the square grid.

The second line contains two space-separated integers $r_1$ and $c_1$ ($1 \leq r_1, c_1 \leq n$) — denoting the cell where Alice resides.

The third line contains two space-separated integers $r_2$ and $c_2$ ($1 \leq r_2, c_2 \leq n$) — denoting the cell to which Alice wishes to travel.

Each of the following $n$ lines contains a string of $n$ characters. The $j$-th character of the $i$-th such line ($1 \leq i, j \leq n$) is 0 if $(i, j)$ is land or 1 if $(i, j)$ is water.

It is guaranteed that $(r_1, c_1)$ and $(r_2, c_2)$ are land.


-----Output-----

Print an integer that is the minimum possible cost of creating at most one tunnel so that Alice could travel from $(r_1, c_1)$ to $(r_2, c_2)$.


-----Examples-----
Input
5
1 1
5 5
00001
11111
00111
00110
00110

Output
10

Input
3
1 3
3 1
010
101
010

Output
8



-----Note-----

In the first sample, a tunnel between cells $(1, 4)$ and $(4, 5)$ should be created. The cost of doing so is $(1-4)^2 + (4-5)^2 = 10$, which is optimal. This way, Alice could walk from $(1, 1)$ to $(1, 4)$, use the tunnel from $(1, 4)$ to $(4, 5)$, and lastly walk from $(4, 5)$ to $(5, 5)$.

In the second sample, clearly a tunnel between cells $(1, 3)$ and $(3, 1)$ needs to be created. The cost of doing so is $(1-3)^2 + (3-1)^2 = 8$.

Difficulty: MEDIUM
Tags: Spanning trees

Graph traversal

Complete search
Skill types: Complete search

Starter code:

Solutions:
import sys
sys.setrecursionlimit(100000000)
n = int(input())
(r1, c1) = map(int, input().strip().split())
(r2, c2) = map(int, input().strip().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
v = [[0 for i in range(n)] for j in range(n)]
mat = []
for i in range(n):
	r = input()
	mat.append(r)

def dfs(node, color):
	x = node[0]
	y = node[1]
	v[x][y] = color
	for (i, j) in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
		xx = x + i
		yy = y + j
		if xx >= 0 and xx <= n - 1 and (yy >= 0) and (yy <= n - 1) and (mat[x][y] == '0' and mat[xx][yy] == '0' or (mat[x][y] == '1' and mat[xx][yy] == '1')) and (v[xx][yy] == 0):
			dfs((xx, yy), color)
land_cnt = 1
river_cnt = -1
for i in range(n):
	for j in range(n):
		if v[i][j] == 0 and mat[i][j] == '0':
			dfs((i, j), land_cnt)
			land_cnt += 1
		elif v[i][j] == 0 and mat[i][j] == '1':
			dfs((i, j), river_cnt)
			river_cnt -= 1
		else:
			pass
color1 = v[r1][c1]
color2 = v[r2][c2]
L1 = []
L2 = []
for i in range(n):
	for j in range(n):
		if v[i][j] == color1:
			L1.append((i, j))
		elif v[i][j] == color2:
			L2.append((i, j))
res = 50000
if color1 == color2:
	print(0)
else:
	for (k1, v1) in L1:
		for (k2, v2) in L2:
			now = (k1 - k2) ** 2 + (v1 - v2) ** 2
			res = min(res, now)
	print(res)


import itertools
n = int(input())
(x1, y1) = [int(a) - 1 for a in input().split()]
(x2, y2) = [int(a) - 1 for a in input().split()]
board = [list(input()) for i in range(n)]

def ma_sens(x, y):
	global board
	return not (x < 0 or x >= n or y < 0 or (y >= n) or (board[x][y] != '0'))

def bfs(x, y, c):
	global board
	tab = [(x, y)]
	pocz = 0
	board[x][y] = c
	while pocz < len(tab):
		(x, y) = tab[pocz]
		pocz += 1
		for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
			if ma_sens(x + dx, y + dy):
				board[x + dx][y + dy] = c
				tab.append((x + dx, y + dy))
	return tab
res = 13337
for (a, b) in itertools.product(bfs(x1, y1, 's'), bfs(x2, y2, 'e')):
	res = min(res, (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
print(res)


from sys import stdin, stdout
import math
N = int(input())
(r1, c1) = [int(x) for x in stdin.readline().split()]
(r2, c2) = [int(x) for x in stdin.readline().split()]
data = []
for i in range(N):
	s = input()
	data.append(list(s))
visited = [[0] * N for _ in range(N)]
dir_x = [-1, 0, 0, 1]
dir_y = [0, -1, 1, 0]
stack = [[r1 - 1, c1 - 1]]
land1 = [[r1 - 1, c1 - 1]]
while stack:
	p = stack.pop()
	visited[p[0]][p[1]] = 1
	for i in range(4):
		x = p[0] + dir_x[i]
		y = p[1] + dir_y[i]
		if x >= 0 and x < N and (y >= 0) and (y < N) and (visited[x][y] == 0) and (data[x][y] == '0'):
			stack.append([x, y])
			land1.append([x, y])
stack = [[r2 - 1, c2 - 1]]
land2 = [[r2 - 1, c2 - 1]]
while stack:
	p = stack.pop()
	visited[p[0]][p[1]] = 2
	for i in range(4):
		x = p[0] + dir_x[i]
		y = p[1] + dir_y[i]
		if x >= 0 and x < N and (y >= 0) and (y < N) and (visited[x][y] == 1) and (data[x][y] == '0'):
			print(0)
			quit()
		if x >= 0 and x < N and (y >= 0) and (y < N) and (visited[x][y] == 0) and (data[x][y] == '0'):
			stack.append([x, y])
			land2.append([x, y])
res = 999999
for p1 in land1:
	for p2 in land2:
		cost = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
		res = min(res, cost)
print(res)


import itertools, sys
n = int(input())
(x1, y1) = [int(a) - 1 for a in input().split()]
(x2, y2) = [int(a) - 1 for a in input().split()]
l = []
for i in range(n):
	l.append(list(input()))

def ma_sens(x, y):
	global l
	return not (x < 0 or x >= n or y < 0 or (y >= n) or (l[x][y] != '0'))

def bfs(x, y, c):
	global l
	tab = [(x, y)]
	pocz = 0
	l[x][y] = c
	while pocz < len(tab):
		(x, y) = tab[pocz]
		pocz += 1
		for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
			if ma_sens(x + dx, y + dy):
				l[x + dx][y + dy] = c
				tab.append((x + dx, y + dy))
	return tab
bla = bfs(x1, y1, '2')
if l[x2][y2] == '2':
	print(0)
	sys.exit()
alb = bfs(x2, y2, '3')
res = 1333337
for (a, b) in itertools.product(bla, alb):
	res = min(res, (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
print(res)


n = int(input())
(r, c) = map(int, input().split())
s = (r - 1, c - 1)
(r, c) = map(int, input().split())
e = (r - 1, c - 1)
grid = []
for n_ in range(n):
	z = input()
	grid.append([int(z[i]) for i in range(n)])
g = []
g.append(s)
found = False
while len(g) > 0:
	(x, y) = g[0]
	if (x, y) == e:
		print(0)
		found = True
		break
	grid[x][y] = 2
	if x > 0:
		if grid[x - 1][y] == 0:
			grid[x - 1][y] = 2
			g.append((x - 1, y))
	if y > 0:
		if grid[x][y - 1] == 0:
			grid[x][y - 1] = 2
			g.append((x, y - 1))
	if x < n - 1:
		if grid[x + 1][y] == 0:
			grid[x + 1][y] = 2
			g.append((x + 1, y))
	if y < n - 1:
		if grid[x][y + 1] == 0:
			grid[x][y + 1] = 2
			g.append((x, y + 1))
	g.remove(g[0])
if found == False:
	(x, y) = e
	nearest = 100000
	g = []
	g.append(e)
	while len(g) > 0:
		(x, y) = g[0]
		grid[x][y] = 3
		for x_ in range(n):
			for y_ in range(n):
				if grid[x_][y_] == 2:
					dist = (x - x_) ** 2 + (y - y_) ** 2
					if dist < nearest:
						nearest = dist
		if x > 0:
			if grid[x - 1][y] == 0:
				g.append((x - 1, y))
		if y > 0:
			if grid[x][y - 1] == 0:
				g.append((x, y - 1))
		if x < n - 1:
			if grid[x + 1][y] == 0:
				g.append((x + 1, y))
		if y < n - 1:
			if grid[x][y + 1] == 0:
				g.append((x, y + 1))
		g.remove(g[0])
	print(nearest)


def f(r1, c1, d):
	T = []
	(m1, n1) = (max(0, r1 - 1), c1)
	(m2, n2) = (r1, max(0, c1 - 1))
	(m3, n3) = (min(n - 1, r1 + 1), c1)
	(m4, n4) = (r1, min(n - 1, c1 + 1))
	if L[m1][n1] == 0 and d[m1][n1] == 0:
		T.append((m1, n1))
		d[m1][n1] = 1
	if L[m2][n2] == 0 and d[m2][n2] == 0:
		T.append((m2, n2))
		d[m2][n2] = 1
	if L[m3][n3] == 0 and d[m3][n3] == 0:
		T.append((m3, n3))
		d[m3][n3] = 1
	if L[m4][n4] == 0 and d[m4][n4] == 0:
		T.append((m4, n4))
		d[m4][n4] = 1
	return T

def solve(r1, c1):
	d = [[0 for i in range(n)] for j in range(n)]
	d[r1][c1] = 1
	S = f(r1, c1, d)
	while S:
		S += f(*S.pop(), d)
	return d
R = lambda : map(int, input().split())
n = int(input())
(r1, c1) = R()
(r2, c2) = R()
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
L = []
for i in range(n):
	L.append([int(j) for j in input()])
P = solve(r1, c1)
Q = solve(r2, c2)
res = 10 ** 9
for i in range(n):
	for j in range(n):
		if P[i][j] == 1:
			for x in range(n):
				for y in range(n):
					if Q[x][y] == 1:
						res = min(res, abs(i - x) ** 2 + abs(j - y) ** 2)
print(res)


n = int(input())
(x1, y1) = map(lambda x: int(x) - 1, input().split())
(x2, y2) = map(lambda x: int(x) - 1, input().split())
matrix = []
for _ in range(n):
	matrix.append(list(input()))
aux = [[] for _ in range(2)]
index = 0
next = [[0, -1], [0, 1], [-1, 0], [1, 0]]

def bfs(x, y):
	q = [[x, y]]
	while len(q):
		(i, j) = q.pop()
		matrix[i][j] = '1'
		aux[index].append([i, j])
		for (a, b) in next:
			if i + a >= 0 and j + b >= 0 and (i + a < n) and (j + b < n):
				if matrix[i + a][j + b] == '0':
					q.append([i + a, j + b])
bfs(x1, y1)
if matrix[x2][y2] == 1:
	print(0)
else:
	index += 1
	bfs(x2, y2)
	ans = 5000
	for (x1, y1) in aux[0]:
		for (x2, y2) in aux[1]:
			ans = min(ans, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(ans)


(N, v) = (55, [])
vis = [[False for x in range(N)] for y in range(N)]

def valid(x, y, n):
	return x >= 0 and x < n and (y >= 0) and (y < n)

def dfs(x, y, n):
	stack = [(x, y)]
	vis[x][y] = True
	while len(stack) > 0:
		(x, y) = stack[-1]
		vis[x][y] = True
		v.append((x, y))
		stack.pop()
		for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			X = x + dx
			Y = y + dy
			if valid(X, Y, n) and vis[X][Y] == False and (grid[X][Y] == '0'):
				stack.append((X, Y))
n = int(input())
(x1, y1) = [int(a) - 1 for a in input().split()]
(x2, y2) = [int(a) - 1 for a in input().split()]
grid = [list(input()) for i in range(n)]
dfs(x1, y1, n)
if vis[x2][y2] == 1:
	(print(0, end=''), exit())
v1 = [x for x in v]
v.clear()
dfs(x2, y2, n)
ans = min([sum([(x - y) ** 2 for (x, y) in zip(a, b)]) for a in v for b in v1])
print(ans, end='')


from sys import setrecursionlimit
import threading
setrecursionlimit(10 ** 9)
threading.stack_size(67108864)

def main():
	dr = [[1, 0], [0, 1], [-1, 0], [0, -1]]

	def dfs(v, i):
		used[v[0]][v[1]] = i
		cm[i - 1] += [v]
		for x in dr:
			u = [v[0] + x[0], v[1] + x[1]]
			if a[u[0]][u[1]] == 0 and used[u[0]][u[1]] == 0:
				dfs(u, i)
	n = int(input())
	s = list(map(int, input().split()))
	f = list(map(int, input().split()))
	a = [list(map(int, list(input()))) + [1] for i in range(n)]
	used = [[0] * n for i in range(n)]
	cm = [[], []]
	a += [[1] * n]
	s[0] -= 1
	s[1] -= 1
	f[0] -= 1
	f[1] -= 1
	dfs(s, 1)
	if used[f[0]][f[1]] == 1:
		print(0)
		exit(0)
	dfs(f, 2)
	ans = 10000
	for p1 in cm[0]:
		for p2 in cm[1]:
			ans = min(ans, (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
	print(ans)
thread = threading.Thread(target=main)
thread.start()


n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
g = []
for i in range(n):
	g.append(input())
d1 = {(r1, c1)}
q = [(r1, c1)]
while q:
	v = q[0]
	(r, c) = v
	if r == r2 and c == c2:
		print(0)
		return
	q = q[1:]
	if r + 1 >= 0 and r + 1 < n:
		nv = (r + 1, c)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d1:
				d1.add(nv)
				q.append(nv)
	if r - 1 >= 0 and r - 1 < n:
		nv = (r - 1, c)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d1:
				d1.add(nv)
				q.append(nv)
	if c + 1 >= 0 and c + 1 < n:
		nv = (r, c + 1)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d1:
				d1.add(nv)
				q.append(nv)
	if c - 1 >= 0 and c - 1 < n:
		nv = (r, c - 1)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d1:
				d1.add(nv)
				q.append(nv)
d2 = {(r2, c2)}
q = [(r2, c2)]
while q:
	v = q[0]
	(r, c) = v
	q = q[1:]
	if r + 1 >= 0 and r + 1 < n:
		nv = (r + 1, c)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d2:
				d2.add(nv)
				q.append(nv)
	if r - 1 >= 0 and r - 1 < n:
		nv = (r - 1, c)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d2:
				d2.add(nv)
				q.append(nv)
	if c + 1 >= 0 and c + 1 < n:
		nv = (r, c + 1)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d2:
				d2.add(nv)
				q.append(nv)
	if c - 1 >= 0 and c - 1 < n:
		nv = (r, c - 1)
		if g[nv[0]][nv[1]] == '0':
			if nv not in d2:
				d2.add(nv)
				q.append(nv)
ans = 10 ** 18
for v1 in d1:
	for v2 in d2:
		ans = min(ans, (v1[0] - v2[0]) ** 2 + (v1[1] - v2[1]) ** 2)
print(ans)


from collections import deque
from heapq import heappush, heappop
N = int(input())
(sy, sx) = map(int, input().split())
(gy, gx) = map(int, input().split())
square = ['2' * (N + 2)] + ['2' + input() + '2' for _ in [0] * N] + ['2' * (N + 2)]

def bfs(startx, starty, v, goal=None):
	if v == 1:
		visited = [[0] * (N + 2) for _ in [0] * (N + 2)]
		visited[starty][startx] = 1
		s = set()
		add = s.add
		dq = deque([(startx, starty)])
		(append, popleft) = (dq.append, dq.popleft)
		while dq:
			(x, y) = popleft()
			add((x, y))
			for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
				if square[ny][nx] == '0' and (not visited[ny][nx]):
					visited[ny][nx] = 1
					append((nx, ny))
		return s
	else:
		visited = [[10 ** 9] * (N + 2) for _ in [0] * (N + 2)]
		visited[starty][startx] = 0
		heap = [(0, startx, starty)]
		while heap:
			(cost, x, y) = heappop(heap)
			if (x, y) in goal:
				return (x, y)
			for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
				new_cost = abs(nx - startx) ** 2 + abs(ny - starty) ** 2
				if square[ny][nx] != '2' and visited[ny][nx] > new_cost:
					visited[ny][nx] = new_cost
					heappush(heap, (new_cost, nx, ny))
		return (10 ** 9, 10 ** 9)
s1 = bfs(sx, sy, 1)
s2 = bfs(gx, gy, 1)
if s1 == s2:
	print(0)
	exit()
ans = 10 ** 9
for (x, y) in s1:
	for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
		if square[ny][nx] == '1':
			(destx, desty) = bfs(nx, ny, 2, s2)
			dist = abs(x - destx) ** 2 + abs(y - desty) ** 2
			if ans > dist:
				ans = dist
print(ans)


import sys
sys.setrecursionlimit(100000)
N = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
A = [[int(a) for a in input()] for i in range(N)]
X = [[0] * N for _ in range(N)]
L = []

def dfs(r, c):
	move = [[0, 1], [0, -1], [-1, 0], [1, 0]]
	X[r][c] = 1
	L.append((r, c))
	for m in move:
		(nr, nc) = (r + m[0], c + m[1])
		if nr >= 0 and nr < N and (nc >= 0) and (nc < N):
			if X[nr][nc] == 0 and A[nr][nc] == 0:
				dfs(nr, nc)
dfs(r1, c1)
if X[r2][c2]:
	print(0)
else:
	LL = [l for l in L]
	L = []
	dfs(r2, c2)
	mi = 10 ** 10
	for ll in LL:
		for l in L:
			mi = min((ll[0] - l[0]) ** 2 + (ll[1] - l[1]) ** 2, mi)
	print(mi)


n = int(input(''))
x = list(map(int, input('').split()))
y = list(map(int, input('').split()))
a = (x[0] - 1, x[1] - 1)
b = (y[0] - 1, y[1] - 1)
x = [input('') for i in range(n)]

def f(var):
	s = []
	if var[0] + 1 < n:
		s.append((var[0] + 1, var[1]))
	if var[1] + 1 < n:
		s.append((var[0], var[1] + 1))
	if var[0] > 0:
		s.append((var[0] - 1, var[1]))
	if var[1] > 0:
		s.append((var[0], var[1] - 1))
	return s
alist = [a]
blist = [b]
while True:
	s = alist[:]
	for i in s:
		for j in f(i):
			if x[j[0]][j[1]] == '0':
				alist.append(j)
	alist = list(set(alist))
	if alist == s:
		break
while True:
	s = blist[:]
	for i in s:
		for j in f(i):
			if x[j[0]][j[1]] == '0':
				blist.append(j)
	blist = list(set(blist))
	if blist == s:
		break
a = n ** 3
for i in alist:
	for j in blist:
		a = min((i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2, a)
print(a)


from sys import stdout
from sys import stdin

def get():
	return stdin.readline().strip()

def getf():
	return [int(i) for i in get().split()]

def put(a, end='\n'):
	stdout.write(str(a) + end)

def putf(a, sep=' ', end='\n'):
	stdout.write(sep.join([str(i) for i in a]) + end)

def bfs(g, i):
	q = [i]
	usd = set()
	while q:
		t = q.pop()
		usd.add(t)
		for j in g[t]:
			if j not in usd:
				q.append(j)
	return usd
from copy import deepcopy
from collections import defaultdict as dd

def main():
	n = int(get())
	(x1, y1) = getf()
	(x2, y2) = getf()
	gr = dd(list)
	s = ['1' * (n + 2)]
	for i in range(n):
		s += ['1' + input() + '1']
	s += ['1' * (n + 2)]
	for i in range(1, n + 1):
		for j in range(1, n + 1):
			if s[i][j] == '0':
				if s[i - 1][j] == '0':
					gr[i, j] += [(i - 1, j)]
				if s[i + 1][j] == '0':
					gr[i, j] += [(i + 1, j)]
				if s[i][j - 1] == '0':
					gr[i, j] += [(i, j - 1)]
				if s[i][j + 1] == '0':
					gr[i, j] += [(i, j + 1)]
	(sa, sb) = (bfs(gr, (x1, y1)), bfs(gr, (x2, y2)))
	res = (x2 - x1) ** 2 + (y2 - y1) ** 2
	for (xa, ya) in sa:
		for (xb, yb) in sb:
			res = min(res, (xa - xb) ** 2 + (ya - yb) ** 2)
	print(res)
main()


n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
matrix = []
for i in range(n):
	matrix.append(input())
moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]

def legal(x, y):
	return 0 <= x < n and 0 <= y < n

def bfs(visited, u, v):
	que = [(u, v)]
	visited.add((u, v))
	while que:
		(u, v) = que[0]
		que = que[1:]
		for m in moves:
			(x, y) = (u + m[0], v + m[1])
			if (x, y) not in visited and legal(x, y) and (matrix[x][y] == '0'):
				visited.add((x, y))
				que.append((x, y))
first = set()
second = set()
bfs(first, r1, c1)
bfs(second, r2, c2)
if (r2, c2) in first:
	print(0)
else:
	res = int(1000000000.0)
	for a in first:
		for b in second:
			res = min(res, (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
	print(res)


def ff(y, x, vis):
	q = [(x, y)]
	vis.add((x, y))
	while q:
		el = q.pop(-1)
		nei = neigh(el[0], el[1])
		for z in nei:
			if grid[z[1]][z[0]] == '1' or z in vis:
				continue
			vis.add(z)
			q.append(z)

def neigh(x, y):
	ls = []
	if x > 0:
		ls.append((x - 1, y))
	if y > 0:
		ls.append((x, y - 1))
	if x < n - 1:
		ls.append((x + 1, y))
	if y < n - 1:
		ls.append((x, y + 1))
	return ls
(n, l1, l2) = (int(input()), list(map(int, input().split())), list(map(int, input().split())))
grid = [list(input()) for _ in range(n)]
knowneighs = [[None] * n for _ in range(n)]
(l1, l2) = ((l1[0] - 1, l1[1] - 1), (l2[0] - 1, l2[1] - 1))
(s, s2) = (set(), set())
ff(l1[0], l1[1], s)
if (l2[1], l2[0]) in s:
	print(0)
else:
	ff(l2[0], l2[1], s2)
	mind = 5000
	print()
	for z1 in s:
		for z2 in s2:
			v = (z1[0] - z2[0]) ** 2 + (z1[1] - z2[1]) ** 2
			if v < mind:
				mind = v
	print(mind)


import sys
n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
a = []
for i in range(n):
	a.append(input())
s = [(r1 - 1, c1 - 1)]
visited = {(i, j): True for i in range(n) for j in range(n)}
sf = []
while s:
	(r, c) = s.pop()
	if c < n - 1 and a[r][c + 1] == '0' and visited[r, c + 1]:
		s.append((r, c + 1))
	if c > 0 and a[r][c - 1] == '0' and visited[r, c - 1]:
		s.append((r, c - 1))
	if r < n - 1 and a[r + 1][c] == '0' and visited[r + 1, c]:
		s.append((r + 1, c))
	if r > 0 and a[r - 1][c] == '0' and visited[r - 1, c]:
		s.append((r - 1, c))
	visited[r, c] = False
	sf.append((r, c))
s = [(r2 - 1, c2 - 1)]
visited = {(i, j): True for i in range(n) for j in range(n)}
df = []
while s:
	(r, c) = s.pop()
	if c < n - 1 and a[r][c + 1] == '0' and visited[r, c + 1]:
		s.append((r, c + 1))
	if c > 0 and a[r][c - 1] == '0' and visited[r, c - 1]:
		s.append((r, c - 1))
	if r < n - 1 and a[r + 1][c] == '0' and visited[r + 1, c]:
		s.append((r + 1, c))
	if r > 0 and a[r - 1][c] == '0' and visited[r - 1, c]:
		s.append((r - 1, c))
	visited[r, c] = False
	df.append((r, c))
d = sys.maxsize
for (x1, y1) in sf:
	for (x2, y2) in df:
		v = (x1 - x2) ** 2 + (y1 - y2) ** 2
		d = min(d, v)
print(d)


from collections import deque
dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]

def travel(sx, sy, cells):
	n = len(cells)
	queue = deque()
	queue.append((sx, sy))
	cells[sx][sy] = 1
	result = [(sx, sy)]
	while len(queue):
		(x, y) = queue.popleft()
		for i in range(len(dirs)):
			(nx, ny) = (x + dirs[i][0], y + dirs[i][1])
			if nx < 0 or ny < 0 or nx >= n or (ny >= n):
				continue
			if cells[nx][ny] == 0:
				queue.append((nx, ny))
				cells[nx][ny] = 1
				result.append((nx, ny))
	return result

def find_best(l1, l2):
	result = float('inf')
	for (c1x, c1y) in l1:
		for (c2x, c2y) in l2:
			result = min(result, (c1x - c2x) * (c1x - c2x) + (c1y - c2y) * (c1y - c2y))
	return result

def solve():
	n = int(input())
	(sx, sy) = map(lambda x: int(x) - 1, input().split())
	(ex, ey) = map(lambda x: int(x) - 1, input().split())
	cells = []
	for i in range(n):
		nums = [int(c) for c in input()]
		cells.append(nums)
	first_land = travel(sx, sy, cells)
	second_land = travel(ex, ey, cells)
	if len(second_land) == 0:
		print(0)
	else:
		print(find_best(first_land, second_land))
solve()


from collections import defaultdict
from itertools import product
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())

def rcIndex(r, c):
	return c + 1 + (r - 1) * (n + 1)
css = []
css.append([1 for i in range(n + 1)])
for r in range(1, n + 1):
	css.append(list(map(int, ' '.join('1' + input() + '1').split())))
css.append([1 for i in range(n + 1)])
parsize = (n + 1) ** 2 + 1
par = [i for i in range(parsize)]
rankList = [1] * parsize

def findRoot(i, par=par):
	if i == par[i]:
		return i
	else:
		root = findRoot(par[i])
		par[i] = root
		return root

def isConnected(i1, i2):
	return findRoot(i1) == findRoot(i2)

def union(i1, i2):
	(root1, root2) = map(findRoot, (i1, i2))
	if not root1 == root2:
		if rankList[root1] <= rankList[root2]:
			par[root1] = root2
		else:
			par[root2] = root1
		if rankList[root1] == rankList[root2]:
			rankList[root2] += 1
for (r, c) in product(range(1, n + 1), repeat=2):
	if css[r][c] == 0:
		if css[r - 1][c] == 0:
			union(rcIndex(r, c), rcIndex(r - 1, c))
		if css[r][c - 1] == 0:
			union(rcIndex(r, c), rcIndex(r, c - 1))
if isConnected(rcIndex(r1, c1), rcIndex(r2, c2)):
	print(0)
	exit()
x = []
y = []
for (r, c) in product(range(1, n + 1), repeat=2):
	if isConnected(rcIndex(r, c), rcIndex(r1, c1)):
		x.append((r, c))
	if isConnected(rcIndex(r, c), rcIndex(r2, c2)):
		y.append((r, c))

def dist(r, c, rp, cp):
	return (r - rp) ** 2 + (c - cp) ** 2
tmp = [dist(r, c, rp, cp) for ((r, c), (rp, cp)) in product(x, y)]
print(min(tmp))


def dfs(planet, r, c):
	n = len(planet)
	r -= 1
	c -= 1
	stack = [(r, c)]
	visited = set()
	while stack:
		curr = stack.pop()
		if curr not in visited:
			visited.add(curr)
			(r, c) = (curr[0], curr[1])
			if r + 1 < n and planet[r + 1][c] == '0':
				stack.append((r + 1, c))
			if c + 1 < n and planet[r][c + 1] == '0':
				stack.append((r, c + 1))
			if r - 1 >= 0 and planet[r - 1][c] == '0':
				stack.append((r - 1, c))
			if c - 1 >= 0 and planet[r][c - 1] == '0':
				stack.append((r, c - 1))
	return visited

def main():
	n = int(input())
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	planet = []
	for i in range(n):
		planet.append(input())
	reach1 = dfs(planet, r1, c1)
	if (r2, c2) in reach1:
		print(0)
		return
	reach2 = dfs(planet, r2, c2)
	min_cost = float('inf')
	for i in reach1:
		(x1, y1) = (i[0], i[1])
		for j in reach2:
			(x2, y2) = (j[0], j[1])
			cost = (x1 - x2) ** 2
			cost += (y1 - y2) ** 2
			min_cost = min(min_cost, cost)
	print(min_cost)
main()


import sys
import threading

def arr_scan():
	return list(map(int, input().split(' ')))
n = arr_scan()[0]
start = arr_scan()
start[0] -= 1
start[1] -= 1
end = arr_scan()
end[0] -= 1
end[1] -= 1
graph = []
for _ in range(n):
	tmp = []
	for num in input().strip():
		tmp.append(int(num))
	graph.append(tmp)
start_water = set()
end_water = set()
found_in_same_set = False
seen = [[-1 for _ in range(n)] for _ in range(n)]

def dfs(start, waterset):
	global graph, seen
	(x, y) = start
	if x < 0 or x >= n or y < 0 or (y >= n):
		return
	if seen[x][y] == 1:
		return
	if graph[x][y] == 1:
		return
	seen[x][y] = 1
	directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
	for direction in directions:
		(x1, y1) = direction
		x2 = x + x1
		y2 = y + y1
		if x2 < 0 or x2 >= n or y2 < 0 or (y2 >= n):
			continue
		if graph[x2][y2] == 1:
			waterset.add(tuple(start))
			continue
		elif (x2, y2) == tuple(end):
			global found_in_same_set
			found_in_same_set = True
		else:
			dfs((x2, y2), waterset)

def main():
	dfs(start, start_water)
	if found_in_same_set == True or start == end:
		print(0)
	else:
		dfs(end, end_water)
		max_cost = -1
		for num1 in start_water:
			for num2 in end_water:
				res = pow(num1[0] - num2[0], 2) + pow(num1[1] - num2[1], 2)
				if res < max_cost or max_cost == -1:
					max_cost = res
		print(max_cost)
sys.setrecursionlimit(5000)
main()


from collections import deque
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
planeta = []
for x in range(n):
	linha = list(input())
	planeta.append(linha)
visitados = [[-1] * n for i in range(n)]

def movimentos_validos(r, c):
	return r >= 0 and c >= 0 and (r <= n - 1) and (c <= n - 1)

def bfs(r, c):
	q = deque()
	alcance = []
	q.insert(0, [r - 1, c - 1])
	alcance.append([r - 1, c - 1])
	while q:
		(l, c) = q.popleft()
		if movimentos_validos(l - 1, c):
			if planeta[l - 1][c] == '0' and visitados[l - 1][c] == -1:
				alcance.append([l - 1, c])
				visitados[l - 1][c] = 1
				q.append([l - 1, c])
		if movimentos_validos(l, c - 1):
			if planeta[l][c - 1] == '0':
				alcance.append([l, c - 1]) and visitados[l, c - 1] == -1
				visitados[l][c - 1] = 1
				q.append([l, c - 1])
		if movimentos_validos(l, c + 1):
			if planeta[l][c + 1] == '0' and visitados[l][c + 1] == -1:
				alcance.append([l, c + 1])
				visitados[l][c + 1] = 1
				q.append([l, c + 1])
		if movimentos_validos(l + 1, c):
			if planeta[l + 1][c] == '0' and visitados[l + 1][c] == -1:
				alcance.append([l + 1, c])
				visitados[l + 1][c] = 1
				q.append([l + 1, c])
	return alcance
a1 = bfs(r1, c1)
a2 = bfs(r2, c2)
if a1 == a2:
	print(0)
else:
	menor = 1000000000.0
	for x in a1:
		for y in a2:
			menor = min(menor, (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2)
	print(menor)


visited = []

def mark(x, y, n):
	visited[x][y] = 1
	if x - 1 >= 0:
		if m[x - 1][y] == '0':
			a[x - 1][y] = 1
			if not visited[x - 1][y]:
				mark(x - 1, y, n)
	if x + 1 < n:
		if m[x + 1][y] == '0':
			a[x + 1][y] = 1
			if not visited[x + 1][y]:
				mark(x + 1, y, n)
	if y - 1 >= 0:
		if m[x][y - 1] == '0':
			a[x][y - 1] = 1
			if not visited[x][y - 1]:
				mark(x, y - 1, n)
	if y + 1 < n:
		if m[x][y + 1] == '0':
			a[x][y + 1] = 1
			if not visited[x][y + 1]:
				mark(x, y + 1, n)

def mark1(x, y, n):
	visited[x][y] = 1
	if x - 1 >= 0:
		if m[x - 1][y] == '0':
			b[x - 1][y] = 1
			if not visited[x - 1][y]:
				mark1(x - 1, y, n)
	if x + 1 < n:
		if m[x + 1][y] == '0':
			b[x + 1][y] = 1
			if not visited[x + 1][y]:
				mark1(x + 1, y, n)
	if y - 1 >= 0:
		if m[x][y - 1] == '0':
			b[x][y - 1] = 1
			if not visited[x][y - 1]:
				mark1(x, y - 1, n)
	if y + 1 < n:
		if m[x][y + 1] == '0':
			b[x][y + 1] = 1
			if not visited[x][y + 1]:
				mark1(x, y + 1, n)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
m = []
for i in range(n):
	m.append(list(input().strip()))
a = []
for i in range(55):
	a.append([0] * 55)
	visited.append([0] * 55)
b = []
for i in range(55):
	b.append([0] * 55)
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
f = 0
a[r1][c1] = 1
mark(r1, c1, n)
if a[r2][c2] == 1:
	f = 1
b[r2][c2] = 1
mark1(r2, c2, n)
ans = 2 * 50 * 50
for i in range(n):
	for j in range(n):
		if a[i][j] == 1:
			for p in range(n):
				for q in range(n):
					if b[p][q] == 1:
						ans = min(ans, (p - i) * (p - i) + (q - j) * (q - j))
if f:
	ans = 0
print(ans)


from collections import defaultdict as dd
import math

def nn():
	return int(input())

def li():
	return list(input())

def mi():
	return list(map(int, input().split()))

def lm():
	return list(map(int, input().split()))
n = nn()
(r1, c1) = mi()
(r2, c2) = mi()
r1 = r1 - 1
c1 = c1 - 1
r2 = r2 - 1
c2 = c2 - 1
g = []
for i in range(n):
	g.append(li())
cc1 = set()
stack = [(r1, c1)]
while stack:
	(r, c) = stack.pop()
	cc1.add((r, c))
	for i in range(-1, 2):
		for j in range(-1, 2):
			if not (i == 0 and j == 0):
				if i == 0 or j == 0:
					if r + i in range(0, n) and c + j in range(0, n):
						if not (r + i, c + j) in cc1:
							if g[r + i][c + j] == '0':
								stack.append((r + i, c + j))
cc2 = set()
stack = [(r2, c2)]
while stack:
	(r, c) = stack.pop()
	cc2.add((r, c))
	for i in range(-1, 2):
		for j in range(-1, 2):
			if not (i == 0 and j == 0):
				if i == 0 or j == 0:
					if r + i in range(0, n) and c + j in range(0, n):
						if not (r + i, c + j) in cc2:
							if g[r + i][c + j] == '0':
								stack.append((r + i, c + j))
dist = 10 * n * n
for (x, y) in cc1:
	for (x1, y1) in cc2:
		d = (x - x1) ** 2 + (y - y1) ** 2
		dist = min(d, dist)
print(dist)


(n,) = map(int, input().split())
(rs, cs) = map(int, input().split())
(rd, cd) = map(int, input().split())
rs -= 1
cs -= 1
rd -= 1
cd -= 1
E = []
for i in range(0, n):
	E.append(list(input().split('\n')[0]))
S = []
D = []
import queue
q = queue.Queue()
q.put((rs, cs))

def get_all_dirs(e):
	dirs = []
	(a, b) = (e[0], e[1])
	if a + 1 < n:
		dirs.append((a + 1, b))
	if a - 1 >= 0:
		dirs.append((a - 1, b))
	if b + 1 < n:
		dirs.append((a, b + 1))
	if b - 1 >= 0:
		dirs.append((a, b - 1))
	return dirs

def process_dirs(e):
	dirs = get_all_dirs(e)
	water = False
	for d in dirs:
		if E[d[0]][d[1]] == '1':
			water = True
		elif E[d[0]][d[1]] == '0':
			q.put(d)
			E[d[0]][d[1]] = '2'
	return water
while not q.empty():
	e = q.get()
	water = process_dirs(e)
	if e[0] == rd and e[1] == cd:
		print(0)
		return
	if water:
		S.append(e)
q.put((rd, cd))
while not q.empty():
	e = q.get()
	water = process_dirs(e)
	if water:
		D.append(e)
import sys

def square(a):
	return a * a

def dis(a, b):
	return square(a[0] - b[0]) + square(a[1] - b[1])
ans = sys.maxsize
for i in S:
	for j in D:
		ans = min(ans, dis(i, j))
print(ans)


from collections import deque
import sys
n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
graph = []
components = []
land_components = {}
visited = set()
for i in range(n):
	row = input()
	graph.append(row)

def find_component(r, c):
	q = deque()
	q.append((r, c))
	queued = set()
	queued.add((r, c))
	result = []
	while q:
		cell = q.popleft()
		result.append(cell)
		consider = []
		(r, c) = cell
		if r > 0 and graph[r - 1][c] == '0':
			consider.append((r - 1, c))
		if c > 0 and graph[r][c - 1] == '0':
			consider.append((r, c - 1))
		if r < n - 1 and graph[r + 1][c] == '0':
			consider.append((r + 1, c))
		if c < n - 1 and graph[r][c + 1] == '0':
			consider.append((r, c + 1))
		for candidate in consider:
			if candidate not in queued:
				q.append(candidate)
				queued.add(candidate)
	return result
comp1 = find_component(r1, c1)
if (r2, c2) in comp1:
	print(0)
	sys.exit()
comp2 = find_component(r2, c2)
best = None
for tuple1 in comp1:
	for tuple2 in comp2:
		dist = pow(tuple1[0] - tuple2[0], 2) + pow(tuple1[1] - tuple2[1], 2)
		if not best or best > dist:
			best = dist
print(best)


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
maze = []
for i in range(n):
	maze.append(input())
list1 = [(r1, c1)]
list2 = [(r2, c2)]
tovisit = [(r1, c1)]
while len(tovisit) > 0:
	(x, y) = tovisit.pop()
	for (cx, cy) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
		if x + cx >= 0 and y + cy >= 0 and (x + cx < n) and (y + cy < n) and ((x + cx, y + cy) not in list1) and (maze[x + cx][y + cy] == '0'):
			list1.append((x + cx, y + cy))
			tovisit.append((x + cx, y + cy))
if (r2, c2) in list1:
	print(0)
	exit()
tovisit = [(r2, c2)]
while len(tovisit) > 0:
	(x, y) = tovisit.pop()
	for (cx, cy) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
		if x + cx >= 0 and y + cy >= 0 and (x + cx < n) and (y + cy < n) and ((x + cx, y + cy) not in list2) and (maze[x + cx][y + cy] == '0'):
			list2.append((x + cx, y + cy))
			tovisit.append((x + cx, y + cy))
mini = 30000000
for i in list1:
	for i2 in list2:
		ans = (i[0] - i2[0]) ** 2 + (i[1] - i2[1]) ** 2
		mini = min(mini, ans)
print(mini)


n = int(input())
s1 = input().split()
s2 = input().split()
(x1, y1) = (int(s1[0]), int(s1[1]))
(x2, y2) = (int(s2[0]), int(s2[1]))
cl = []
for i in range(n):
	cl.append(input())
dl = [[0 for _ in range(n)] for _ in range(n)]
dl[x1 - 1][y1 - 1] = 1
st1 = True
for _ in range(n + 1):
	if st1:
		for i in range(x1 - 1, n):
			for j in range(y1 - 1, n):
				if cl[i][j] != '1' and dl[i][j] != 1:
					if i > 0 and dl[i - 1][j] == 1 or (i < n - 1 and dl[i + 1][j] == 1) or (j > 0 and dl[i][j - 1] == 1) or (j < n - 1 and dl[i][j + 1] == 1):
						dl[i][j] = 1
			for j in range(y1 - 1, -1, -1):
				if cl[i][j] != '1' and dl[i][j] != 1:
					if i > 0 and dl[i - 1][j] == 1 or (i < n - 1 and dl[i + 1][j] == 1) or (j > 0 and dl[i][j - 1] == 1) or (j < n - 1 and dl[i][j + 1] == 1):
						dl[i][j] = 1
		for i in range(x1 - 1, -1, -1):
			for j in range(y1 - 1, n):
				if cl[i][j] != '1' and dl[i][j] != 1:
					if i > 0 and dl[i - 1][j] == 1 or (i < n - 1 and dl[i + 1][j] == 1) or (j > 0 and dl[i][j - 1] == 1) or (j < n - 1 and dl[i][j + 1] == 1):
						dl[i][j] = 1
			for j in range(y1 - 1, -1, -1):
				if cl[i][j] != '1' and dl[i][j] != 1:
					if i > 0 and dl[i - 1][j] == 1 or (i < n - 1 and dl[i + 1][j] == 1) or (j > 0 and dl[i][j - 1] == 1) or (j < n - 1 and dl[i][j + 1] == 1):
						dl[i][j] = 1
		st1 = False
	else:
		for i in range(n):
			for j in range(n):
				if cl[i][j] != '1' and dl[i][j] != 1:
					if i > 0 and dl[i - 1][j] == 1 or (i < n - 1 and dl[i + 1][j] == 1) or (j > 0 and dl[i][j - 1] == 1) or (j < n - 1 and dl[i][j + 1] == 1):
						dl[i][j] = 1
		st1 = False
if dl[x2 - 1][y2 - 1] == 1:
	print(0)
else:
	dl2 = [[0 for _ in range(n)] for _ in range(n)]
	mn = 10000000.0
	dl2[x2 - 1][y2 - 1] = 1
	st2 = True
	for _ in range(n + 1):
		if st2:
			for i in range(x1 - 1, n):
				for j in range(y1 - 1, n):
					if cl[i][j] != '1' and dl2[i][j] != 1:
						if i > 0 and dl2[i - 1][j] == 1 or (i < n - 1 and dl2[i + 1][j] == 1) or (j > 0 and dl2[i][j - 1] == 1) or (j < n - 1 and dl2[i][j + 1] == 1):
							dl2[i][j] = 1
				for j in range(y1 - 1, -1, -1):
					if cl[i][j] != '1' and dl2[i][j] != 1:
						if i > 0 and dl2[i - 1][j] == 1 or (i < n - 1 and dl2[i + 1][j] == 1) or (j > 0 and dl2[i][j - 1] == 1) or (j < n - 1 and dl2[i][j + 1] == 1):
							dl2[i][j] = 1
			for i in range(x1 - 1, -1, -1):
				for j in range(y1 - 1, n):
					if cl[i][j] != '1' and dl2[i][j] != 1:
						if i > 0 and dl2[i - 1][j] == 1 or (i < n - 1 and dl2[i + 1][j] == 1) or (j > 0 and dl2[i][j - 1] == 1) or (j < n - 1 and dl2[i][j + 1] == 1):
							dl2[i][j] = 1
				for j in range(y1 - 1, -1, -1):
					if cl[i][j] != '1' and dl2[i][j] != 1:
						if i > 0 and dl2[i - 1][j] == 1 or (i < n - 1 and dl2[i + 1][j] == 1) or (j > 0 and dl2[i][j - 1] == 1) or (j < n - 1 and dl2[i][j + 1] == 1):
							dl2[i][j] = 1
			st2 = False
		else:
			for i in range(n):
				for j in range(n):
					if cl[i][j] != '1' and dl2[i][j] != 1:
						if i > 0 and dl2[i - 1][j] == 1 or (i < n - 1 and dl2[i + 1][j] == 1) or (j > 0 and dl2[i][j - 1] == 1) or (j < n - 1 and dl2[i][j + 1] == 1):
							dl2[i][j] = 1
			st1 = False
	a1 = []
	a2 = []
	for i in range(n):
		for j in range(n):
			if dl[i][j] == 1:
				a1.append((i, j))
			if dl2[i][j] == 1:
				a2.append((i, j))
	for x in a1:
		for y in a2:
			d = (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2
			if d < mn:
				mn = d
	print(mn)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = []
for _ in range(n):
	a.append(input())
(island1, island2) = ([], [])

def dfs(r, c, island):
	if (r, c) in island:
		return
	if r >= n or c >= n or r < 0 or (c < 0):
		return
	if a[r][c] == '1':
		return
	island.append((r, c))
	dfs(r - 1, c, island)
	dfs(r + 1, c, island)
	dfs(r, c - 1, island)
	dfs(r, c + 1, island)
dfs(r1 - 1, c1 - 1, island1)
if (r2 - 1, c2 - 1) in island1:
	print(0)
else:
	dfs(r2 - 1, c2 - 1, island2)
	ans = 10 ** 9
	for p1 in island1:
		for p2 in island2:
			rast = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
			if rast < ans:
				ans = rast
	print(ans)


from sys import stdin, stdout

def find(node):
	x = []
	while dsu[node] > 0:
		x.append(node)
		node = dsu[node]
	for i in x:
		dsu[i] = node
	return node

def union(node1, node2):
	if node1 != node2:
		if dsu[node1] > dsu[node2]:
			(node1, node2) = (node2, node1)
		dsu[node1] += dsu[node2]
		dsu[node2] = node1
n = int(stdin.readline().strip())
dsu = [-1 for i in range(n ** 2 + 1)]
(a, b) = map(int, stdin.readline().strip().split())
(c, d) = map(int, stdin.readline().strip().split())
s = ' '
for i in range(n):
	cur = stdin.readline().strip()
	s += cur
	for j in range(n):
		if cur[j] == '0':
			if j != 0:
				if cur[j - 1] == '0':
					union(find(i * n + j), find(i * n + (j + 1)))
			if i != 0:
				if s[(i - 1) * n + j + 1] == '0':
					union(find(i * n + j + 1), find((i - 1) * n + j + 1))
p_a = find((a - 1) * n + b)
p_b = find((c - 1) * n + d)
if p_a == p_b:
	stdout.write('0')
else:
	arr_a = []
	arr_b = []
	for i in range(1, n ** 2 + 1):
		c_p = find(i)
		if c_p == p_a:
			arr_a.append(i)
		elif c_p == p_b:
			arr_b.append(i)
		else:
			continue
	minm = 5000
	for i in arr_a:
		x1 = i // n if i % n == 0 else i // n + 1
		y1 = i - (x1 - 1) * n
		for j in arr_b:
			x2 = j // n if j % n == 0 else j // n + 1
			y2 = j - (x2 - 1) * n
			val = abs(x2 - x1) ** 2 + abs(y2 - y1) ** 2
			minm = min(minm, val)
	stdout.write(f'{minm}')


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
matrix = []
s1 = set()
s2 = set()
r1 = r1 - 1
r2 = r2 - 1
c1 = c1 - 1
c2 = c2 - 1
for i in range(n):
	s = input()
	matrix.append(s)
stack = [(r1, c1)]
visited = set()
while len(stack):
	(r, c) = stack.pop()
	s1.add((r, c))
	visited.add((r, c))
	if r > 0 and matrix[r - 1][c] == '0' and ((r - 1, c) not in visited):
		stack.append((r - 1, c))
		visited.add((r - 1, c))
		s1.add((r - 1, c))
	if r < n - 1 and matrix[r + 1][c] == '0' and ((r + 1, c) not in visited):
		stack.append((r + 1, c))
		s1.add((r + 1, c))
		visited.add((r + 1, c))
	if c > 0 and matrix[r][c - 1] == '0' and ((r, c - 1) not in visited):
		stack.append((r, c - 1))
		s1.add((r, c - 1))
		visited.add((r, c - 1))
	if c < n - 1 and matrix[r][c + 1] == '0' and ((r, c + 1) not in visited):
		stack.append((r, c + 1))
		s1.add((r, c + 1))
		visited.add((r, c + 1))
stack = [(r2, c2)]
visited = set()
while len(stack):
	(r, c) = stack.pop()
	s2.add((r, c))
	visited.add((r, c))
	if r > 0 and matrix[r - 1][c] == '0' and ((r - 1, c) not in visited):
		stack.append((r - 1, c))
		visited.add((r - 1, c))
		s2.add((r - 1, c))
	if r < n - 1 and matrix[r + 1][c] == '0' and ((r + 1, c) not in visited):
		stack.append((r + 1, c))
		visited.add((r + 1, c))
		s2.add((r + 1, c))
	if c > 0 and matrix[r][c - 1] == '0' and ((r, c - 1) not in visited):
		stack.append((r, c - 1))
		visited.add((r, c - 1))
		s2.add((r, c - 1))
	if c < n - 1 and matrix[r][c + 1] == '0' and ((r, c + 1) not in visited):
		stack.append((r, c + 1))
		visited.add((r, c + 1))
		s2.add((r, c + 1))
x = float('inf')
for i in s1:
	for j in s2:
		x = min(x, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(x)


from collections import deque

def BFS(a, vertex=None):
	if vertex is None:
		vertex = 1
	s = [1] * len(a)
	d = deque([vertex])
	s[vertex] = 0
	f = {vertex}
	while len(d) > 0:
		for q in a[d.popleft()]:
			if s[q]:
				d.append(q)
				f.add(q)
				s[q] = 0
	return f

def components(a):
	s = [1] * len(a)
	(d, q2) = ([], 1)
	while q2 < len(a):
		if s[q2]:
			if len(a[q2]) == 0:
				s[q2] = 0
				d.append({q2})
			else:
				f = BFS(a, q2)
				d.append(f)
				for q in f:
					s[q] = 0
		else:
			q2 += 1
	return d
n = int(input())
(x1, y1) = map(int, input().split())
(x2, y2) = map(int, input().split())
a = [[0] * (n + 2)] + [[0] + list(map(int, [1 - int(q) for q in list(input())])) + [0] for _ in range(n)] + [[0] * (n + 2)]
d = [[] for _ in range(n ** 2 + 1)]
for q in range(1, n + 1):
	for q1 in range(1, n + 1):
		if a[q][q1]:
			if a[q - 1][q1]:
				d[(q - 1) * n + q1].append((q - 2) * n + q1)
			if a[q + 1][q1]:
				d[(q - 1) * n + q1].append(q * n + q1)
			if a[q][q1 - 1]:
				d[(q - 1) * n + q1].append((q - 1) * n + q1 - 1)
			if a[q][q1 + 1]:
				d[(q - 1) * n + q1].append((q - 1) * n + q1 + 1)
(x, y) = ((x1 - 1) * n + y1, (x2 - 1) * n + y2)
s = components(d)
(comp_x, comp_y) = ([], [])
for q in s:
	if x in q:
		comp_x = q
	if y in q:
		comp_y = q
if comp_y == comp_x:
	print(0)
else:
	ans = float('inf')
	for q in comp_x:
		for q1 in comp_y:
			(x1, x2, y1, y2) = ((q - 1) // n + 1, (q - 1) % n + 1, (q1 - 1) // n + 1, (q1 - 1) % n + 1)
			ans = min((x1 - y1) ** 2 + (x2 - y2) ** 2, ans)
	print(ans)


from collections import defaultdict

def bfs(node, bool):
	queue = [node]
	bool[node] = True
	while queue:
		(i, j) = queue.pop(0)
		za = [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]
		for i in za:
			if 0 <= i[0] <= n and 0 <= i[1] <= n:
				if bool[i] == False and l[i[0] - 1][i[1] - 1] == '0':
					bool[i] = True
					queue.append(i)
bool1 = defaultdict(bool)
bool2 = defaultdict(bool)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
l = []
for i in range(n):
	z = list(input())
	l.append(z)
mini = 10 ** 18
bfs((r1, c1), bool1)
bfs((r2, c2), bool2)
for i in bool1:
	if bool1[i]:
		for j in bool2:
			if bool2[j]:
				(a, b) = i
				(c, d) = j
				mini = min((a - c) ** 2 + (b - d) ** 2, mini)
print(mini)


import sys
sys.setrecursionlimit(100000)

def hypot(a, b):
	return a ** 2 + b ** 2

def bfs0(r, c):
	nonlocal used
	used[r][c] = True
	comp0.append((r, c))
	if r > 0:
		if not used[r - 1][c] and matr[r - 1][c]:
			bfs0(r - 1, c)
	if r < n - 1:
		if not used[r + 1][c] and matr[r + 1][c]:
			bfs0(r + 1, c)
	if c > 0:
		if not used[r][c - 1] and matr[r][c - 1]:
			bfs0(r, c - 1)
	if c < n - 1:
		if not used[r][c + 1] and matr[r][c + 1]:
			bfs0(r, c + 1)

def bfs1(r, c):
	nonlocal used
	used[r][c] = True
	comp1.append((r, c))
	if r > 0:
		if not used[r - 1][c] and matr[r - 1][c]:
			bfs1(r - 1, c)
	if r < n - 1:
		if not used[r + 1][c] and matr[r + 1][c]:
			bfs1(r + 1, c)
	if c > 0:
		if not used[r][c - 1] and matr[r][c - 1]:
			bfs1(r, c - 1)
	if c < n - 1:
		if not used[r][c + 1] and matr[r][c + 1]:
			bfs1(r, c + 1)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
matr = [[] for i in range(n)]
for i in range(n):
	for el in input():
		if el == '0':
			matr[i].append(True)
		else:
			matr[i].append(False)
used = [[False] * n for i in range(n)]
comp0 = []
bfs0(r1 - 1, c1 - 1)
if used[r2 - 1][c2 - 1]:
	print(0)
else:
	comp1 = []
	mi = 100000000000000
	bfs1(r2 - 1, c2 - 1)
	for el in comp0:
		for ell in comp1:
			mi = min(hypot(ell[0] - el[0], ell[1] - el[1]), mi)
	print(mi)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
(startI, startJ) = map(lambda x: int(x) - 1, input().split())
(endI, endJ) = map(lambda x: int(x) - 1, input().split())
a = [input().strip() for _ in range(n)]

def dfs(i, j, comp):
	visited[i][j] = True
	comp.append((i, j))
	for di in range(-1, 2):
		for dj in range(-1, 2):
			if di * di + dj * dj == 1:
				(ni, nj) = (i + di, j + dj)
				if 0 <= ni < n and 0 <= nj < n and (a[ni][nj] == '0') and (not visited[ni][nj]):
					dfs(ni, nj, comp)
start = []
visited = [[False for _ in range(n)] for _ in range(n)]
dfs(startI, startJ, start)
end = []
dfs(endI, endJ, end)
ret = 1 << 30
for startPos in start:
	for endPos in end:
		ret = min(ret, abs(startPos[0] - endPos[0]) ** 2 + abs(startPos[1] - endPos[1]) ** 2)
print(ret)


n = int(input())
(x1, y1) = list(map(int, input().split()))
(x2, y2) = list(map(int, input().split()))
x1 -= 1
x2 -= 1
y1 -= 1
y2 -= 1
a = []
for i in range(n):
	a.append(list(map(int, list(input()))))
for i in range(n):
	for j in range(n):
		a[i][j] = 1 - a[i][j]
vis = []
for i in range(n):
	vis.append([0] * n)
bfsQ = [[x1, y1]]
vis[x1][y1] = 1
while bfsQ:
	(i, j) = bfsQ[0]
	del bfsQ[0]
	if i == x2 and j == y2:
		print(0)
		break
	if i < n - 1 and a[i + 1][j] and (vis[i + 1][j] == 0):
		vis[i + 1][j] = 1
		bfsQ.append([i + 1, j])
	if j < n - 1 and a[i][j + 1] and (vis[i][j + 1] == 0):
		vis[i][j + 1] = 1
		bfsQ.append([i, j + 1])
	if i > 0 and a[i - 1][j] and (vis[i - 1][j] == 0):
		vis[i - 1][j] = 1
		bfsQ.append([i - 1, j])
	if j > 0 and a[i][j - 1] and (vis[i][j - 1] == 0):
		vis[i][j - 1] = 1
		bfsQ.append([i, j - 1])
else:
	bfsQ = [[x2, y2]]
	vis[x2][y2] = 2
	while bfsQ:
		(i, j) = bfsQ[0]
		del bfsQ[0]
		if i < n - 1 and a[i + 1][j] and (vis[i + 1][j] == 0):
			vis[i + 1][j] = 2
			bfsQ.append([i + 1, j])
		if j < n - 1 and a[i][j + 1] and (vis[i][j + 1] == 0):
			vis[i][j + 1] = 2
			bfsQ.append([i, j + 1])
		if i > 0 and a[i - 1][j] and (vis[i - 1][j] == 0):
			vis[i - 1][j] = 2
			bfsQ.append([i - 1, j])
		if j > 0 and a[i][j - 1] and (vis[i][j - 1] == 0):
			vis[i][j - 1] = 2
			bfsQ.append([i, j - 1])
	land1 = []
	land2 = []
	for i in range(n):
		for j in range(n):
			if vis[i][j] == 1:
				land1.append([i, j])
			if vis[i][j] == 2:
				land2.append([i, j])
	mini = 999999999999999999999999
	for (x1, y1) in land1:
		for (x2, y2) in land2:
			mini = min(mini, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(mini)


n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
A = [[-1 for i in range(n + 2)] for i in range(n + 2)]
for i in range(1, n + 1):
	a = input()
	for j in range(n):
		A[i][j + 1] = int(a[j])
(x, y) = (r1, c1)
V = [[0 for i in range(n + 2)] for i in range(n + 2)]
V[x][y] = 1
S = [[x, y]]
k = 0
while k < len(S):
	x = S[k][0]
	y = S[k][1]
	if A[x + 1][y] == 0 and V[x + 1][y] == 0:
		S.append([x + 1, y])
		V[x + 1][y] = 1
	if A[x - 1][y] == 0 and V[x - 1][y] == 0:
		S.append([x - 1, y])
		V[x - 11][y] = 1
	if A[x][y - 1] == 0 and V[x][y - 1] == 0:
		S.append([x, y - 1])
		V[x][y - 1] = 1
	if A[x][y + 1] == 0 and V[x][y + 1] == 0:
		S.append([x, y + 1])
		V[x][y + 1] = 1
	k += 1
if [r2, c2] in S:
	print(0)
else:
	(x, y) = (r2, c2)
	V = [[0 for i in range(n + 2)] for i in range(n + 2)]
	V[x][y] = 1
	F = [[x, y]]
	k = 0
	while k < len(F):
		x = F[k][0]
		y = F[k][1]
		if A[x + 1][y] == 0 and V[x + 1][y] == 0:
			F.append([x + 1, y])
			V[x + 1][y] = 1
		if A[x - 1][y] == 0 and V[x - 1][y] == 0:
			F.append([x - 1, y])
			V[x - 1][y] = 1
		if A[x][y - 1] == 0 and V[x][y - 1] == 0:
			F.append([x, y - 1])
			V[x][y - 1] = 1
		if A[x][y + 1] == 0 and V[x][y + 1] == 0:
			F.append([x, y + 1])
			V[x][y + 1] = 1
		k += 1
	mins = 100000000000000
	for fr in S:
		for sd in F:
			mins = min((fr[0] - sd[0]) ** 2 + (fr[1] - sd[1]) ** 2, mins)
	print(mins)


from sys import stdin, exit, setrecursionlimit
from typing import List, Tuple
setrecursionlimit(50 * 50)
vectors = [(1, 0), (0, 1), (-1, 0), (0, -1)]
ALICE_LAND = 1
DEST_LAND = 2

class Position:
	owner: int
	next_to_water: bool
	is_land: bool
	explored: bool

	def __init__(self, owner: int, is_land: bool, next_to_water: bool=False):
		self.owner = owner
		self.next_to_water = next_to_water
		self.is_land = is_land
		self.explored = False

	def __repr__(self):
		return str(int(self.next_to_water))

def explore_map(gmap: List[List[Position]], row: int, col: int, claim_ownership: int):
	if gmap[row][col].explored:
		return
	this = gmap[row][col]
	this.explored = True
	this.is_land = True
	this.owner = claim_ownership
	for vec in vectors:
		if 0 <= row + vec[0] < len(gmap) and 0 <= col + vec[1] < len(gmap):
			if not gmap[row + vec[0]][col + vec[1]].is_land:
				this.next_to_water = True
			else:
				explore_map(gmap, row + vec[0], col + vec[1], claim_ownership)
try:
	n = int(stdin.readline().rstrip())
	start = [int(v) - 1 for v in stdin.readline().rstrip().split()]
	end = [int(v) - 1 for v in stdin.readline().rstrip().split()]
	gmap: List[List[Position]] = [None] * n
	for i in range(n):
		gmap[i] = [Position(0, not bool(int(v))) for v in stdin.readline().rstrip()]
	explore_map(gmap, *start, ALICE_LAND)
	explore_map(gmap, *end, DEST_LAND)
	if gmap[end[0]][end[1]].owner == ALICE_LAND:
		print(0)
		exit(0)
	alice_coast: List[Tuple[int, int]] = []
	dest_coast: List[Tuple[int, int]] = []
	for i in range(len(gmap)):
		for j in range(len(gmap)):
			if gmap[i][j].owner == ALICE_LAND:
				alice_coast.append((i, j))
			elif gmap[i][j].owner == DEST_LAND:
				dest_coast.append((i, j))
	rez: int = float('inf')
	for (alice_row, alice_col) in alice_coast:
		for (dest_row, dest_col) in dest_coast:
			rez = min(rez, (alice_row - dest_row) ** 2 + (alice_col - dest_col) ** 2)
	print(rez)
except Exception as e:
	print(str(e))


n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
mat = []
for i in range(n):
	mat.append(list(map(str, input())))
vis = [[False for i in range(n)] for i in range(n)]
coor = [[1, 0], [0, 1], [-1, 0], [0, -1]]
(r1, c1, r2, c2) = (r1 - 1, c1 - 1, r2 - 1, c2 - 1)
q = []
q.append([r1, c1])
vis[r1][c1] = True
path1 = [[r1, c1]]
f = 0
while q != []:
	(x, y) = (q[0][0], q[0][1])
	q.pop(0)
	for v in coor:
		(a, b) = (x + v[0], y + v[1])
		if a >= 0 and a < n and (b >= 0) and (b < n):
			if vis[a][b] == False and mat[a][b] != '1':
				vis[a][b] = True
				if a == r2 and b == c2:
					f = 1
				path1.append([a, b])
				q.append([a, b])
if f == 1:
	print(0)
else:
	vis = [[False for i in range(n)] for i in range(n)]
	q = []
	q.append([r2, c2])
	vis[r2][c2] = True
	path2 = [[r2, c2]]
	f = 0
	while q != []:
		(x, y) = (q[0][0], q[0][1])
		q.pop(0)
		for v in coor:
			(a, b) = (x + v[0], y + v[1])
			if a >= 0 and a < n and (b >= 0) and (b < n):
				if vis[a][b] == False and mat[a][b] != '1':
					vis[a][b] = True
					if a == r1 and b == c1:
						f = 1
					path2.append([a, b])
					q.append([a, b])
	if f == 1:
		print(0)
	else:
		cost = 10 ** 10
		for i in path1:
			for j in path2:
				(u, v) = (i[0], i[1])
				(x, y) = (j[0], j[1])
				val = (x - u) ** 2 + (y - v) ** 2
				cost = min(cost, val)
		print(cost)


import sys
sys.setrecursionlimit(100000000)
step = [(1, 0), (-1, 0), (0, -1), (0, 1)]

def find_components(comp, point, matrix, Row):
	for (i, j) in step:
		(new_i, new_j) = (point[0] + i, point[1] + j)
		if new_i >= Row or new_i < 0 or new_j >= Row or (new_j < 0) or (matrix[new_i][new_j] != 0) or ((new_i, new_j) in comp):
			continue
		comp.add((new_i, new_j))
		find_components(comp, (new_i, new_j), matrix, Row)
Row = int(input().strip())
start = tuple((i - 1 for i in list(map(int, input().strip().split()))))
end = tuple((i - 1 for i in list(map(int, input().strip().split()))))
adj_matrix = []
for i in range(Row):
	adj_matrix.append([int(i) for i in input().strip()])
component1 = set([start])
component2 = set([end])
find_components(component1, start, adj_matrix, Row)
find_components(component2, end, adj_matrix, Row)
mini = 100000000000
if start in component2:
	print(0)
else:
	for i in component1:
		for j in component2:
			cost = (i[0] - j[0]) * (i[0] - j[0]) + (i[1] - j[1]) * (i[1] - j[1])
			if cost < mini:
				mini = cost
	print(mini)


import sys
input = sys.stdin.readline
sys.setrecursionlimit(99999)
n = int(input())
(x, y) = map(int, input().split())
(r, c) = map(int, input().split())
adj = [list(map(int, input().rstrip())) for _ in range(n)]
dx = [0, 0, -1, 1]
dy = dx[::-1]
valid = lambda x, y: 0 <= x < n and 0 <= y < n
visit = [[False] * 51 for _ in range(51)]

def dfs(x, y, ans):
	if visit[x][y]:
		return
	visit[x][y] = True
	ans.append((x, y))
	for i in range(4):
		nx = x + dx[i]
		ny = y + dy[i]
		if not valid(nx, ny):
			continue
		if adj[nx][ny]:
			continue
		dfs(nx, ny, ans)
start = []
end = []
dfs(x - 1, y - 1, start)
if (r - 1, c - 1) in start:
	print(0)
	exit()
dfs(r - 1, c - 1, end)
ans = 10 ** 100
for (x, y) in start:
	for (a, b) in end:
		ans = min(ans, (a - x) ** 2 + (y - b) ** 2)
print(ans)


from collections import defaultdict

def x_of(point):
	return point[0]

def y_of(point):
	return point[1]

def connected(point, world, con, visited):
	stack = []
	stack.append(point)
	con.append(point)
	visited[point] = True
	x = [0, -1, 0, 1]
	y = [-1, 0, 1, 0]
	while stack != []:
		p = stack.pop()
		for i in range(4):
			neighbor = (x_of(p) + x[i], y_of(p) + y[i])
			is_in_boundaries = 0 <= x_of(neighbor) < len(world) and 0 <= y_of(neighbor) < len(world)
			if is_in_boundaries and world[x_of(neighbor)][y_of(neighbor)] == 0 and (not visited[neighbor]):
				stack.append(neighbor)
				con.append(neighbor)
				visited[neighbor] = True
	return con
n = int(input())
origin = tuple(map(lambda x: int(x) - 1, input().split()))
destination = tuple(map(lambda x: int(x) - 1, input().split()))
world = []
for i in range(n):
	world.append(list(map(int, list(input()))))
land1 = connected(origin, world, [], defaultdict(lambda : False))
land2 = connected(destination, world, [], defaultdict(lambda : False))
if sorted(land1) == sorted(land2):
	print(0)
else:
	fix = lambda a: (a[0] + 1, a[1] + 1)
	cost = lambda a, b: (x_of(a) - x_of(b)) ** 2 + (y_of(a) - y_of(b)) ** 2
	m = cost(land1[0], land2[0])
	for l1 in land1:
		for l2 in land2:
			m = min(m, cost(l1, l2))
	print(m)


import sys
sys.setrecursionlimit(3000)

def dfs(a, x, y, n, used, m):
	used[x][y] = 1
	for i in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
		(x1, y1) = (x + i[0], y + i[1])
		if 0 <= x1 < n and 0 <= y1 < n and (a[x1][y1] == 0):
			if used[x1][y1] == 0:
				v = m[:]
				v.append((x1, y1))
				(qx, m) = dfs(a, x1, y1, n, used, v)
	return (used, m)
n = int(input())
(x1, y1) = map(int, input().split())
(x2, y2) = map(int, input().split())
x1 -= 1
x2 -= 1
y1 -= 1
y2 -= 1
a = [[int(j) for j in input()] for i in range(n)]
a1 = [(x1, y1)]
a2 = [(x2, y2)]
used1 = [[0] * n for i in range(n)]
(used1, a1) = dfs(a, x1, y1, n, used1, a1)
used2 = [[0] * n for i in range(n)]
(used2, a2) = dfs(a, x2, y2, n, used2, a2)
mi = 10 ** 10
for x in a1:
	for y in a2:
		if x == y:
			print(0)
			sys.exit(0)
		mi = min((x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2, mi)
print(mi)


n = int(input())
(s1, s2) = map(lambda x: int(x) - 1, input().split())
(e1, e2) = map(lambda x: int(x) - 1, input().split())
m = []
for _ in range(n):
	m.append(list(input()))
uni = [[] for _ in range(2)]
s = 0
next = [[0, -1], [0, 1], [-1, 0], [1, 0]]

def bfs(x, y):
	q = [[x, y]]
	while len(q):
		(i, j) = q.pop()
		m[i][j] = '1'
		uni[s].append([i, j])
		for (a, b) in next:
			ni = i + a
			nj = j + b
			if ni >= 0 and nj >= 0 and (ni < n) and (nj < n):
				if m[ni][nj] == '0':
					q.append([ni, nj])
bfs(s1, s2)
if m[e1][e2] == 1:
	print(0)
else:
	s += 1
	bfs(e1, e2)
	res = 5000
	for (x1, y1) in uni[0]:
		for (x2, y2) in uni[1]:
			res = min(res, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(res)


from sys import maxsize
n = int(input())
(xo, yo) = map(int, input().split())
(x1, y1) = map(int, input().split())
grid = []
setS = set()
setT = set()
gridVisit = []
for i in range(n):
	inp = input()
	arr = []
	visit = []
	for j in range(n):
		arr.append(inp[j])
		visit.append(False)
	gridVisit.append(visit)
	grid.append(arr)

def dfs(x, y, setFlag):
	if setFlag:
		if x == x1 - 1 and y == y1 - 1:
			print(0)
			exit(0)
	if not setFlag:
		if x == xo - 1 and y == yo - 1:
			print(0)
			exit(0)
	if grid[x][y] != '1' and (not gridVisit[x][y]):
		gridVisit[x][y] = True
		if setFlag:
			setS.add((x, y))
		else:
			setT.add((x, y))
		if x + 1 < n and grid[x + 1][y] != '1':
			dfs(x + 1, y, setFlag)
		if y + 1 < n and grid[x][y + 1] != '1':
			dfs(x, y + 1, setFlag)
		if x - 1 >= 0 and grid[x - 1][y] != '1':
			dfs(x - 1, y, setFlag)
		if y - 1 >= 0 and grid[x][y - 1] != '1':
			dfs(x, y - 1, setFlag)
currVal = maxsize
dfs(xo - 1, yo - 1, True)
dfs(x1 - 1, y1 - 1, False)
minVal = maxsize
for i in setS:
	for j in setT:
		minVal = min(minVal, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(minVal)


import sys
sys.setrecursionlimit(536870912)

def dfs(i, j, vis, g, c):
	vis[i][j] = 1
	c.append((i, j))
	if i > 0 and vis[i - 1][j] == 0 and (g[i - 1][j] == '0'):
		dfs(i - 1, j, vis, g, c)
	if i < n - 1 and vis[i + 1][j] == 0 and (g[i + 1][j] == '0'):
		dfs(i + 1, j, vis, g, c)
	if j < n - 1 and vis[i][j + 1] == 0 and (g[i][j + 1] == '0'):
		dfs(i, j + 1, vis, g, c)
	if j > 0 and vis[i][j - 1] == 0 and (g[i][j - 1] == '0'):
		dfs(i, j - 1, vis, g, c)
n = int(input())
(r1, c1) = map(int, input().split())
r1 -= 1
c1 -= 1
(r2, c2) = map(int, input().split())
r2 -= 1
c2 -= 1
g = []
for i in range(n):
	g.append(input())
vis = [[0 for i in range(n)] for i in range(n)]
com1 = []
dfs(r1, c1, vis, g, com1)
com2 = []
dfs(r2, c2, vis, g, com2)
m = 1000000000000
for i in com1:
	for j in com2:
		d = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
		m = min(m, d)
print(m)


from collections import deque

def bfs(start):
	q = [start]
	q = deque(q)
	allnodes = [start]
	visited[start] = 1
	while len(q) != 0:
		element = q.popleft()
		for i in graph[element]:
			if visited[tuple(i)] == 0:
				q.append(tuple(i))
				allnodes.append(tuple(i))
				visited[tuple(i)] = 1
	return allnodes
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
graph = {}
m = []
for i in range(n):
	s = list(input())
	m.append(s)
visited = {}
for i in range(n):
	for j in range(n):
		if m[i][j] == '0':
			if i > 0:
				if m[i - 1][j] == '0':
					if (i, j) in graph:
						graph[i, j].append([i - 1, j])
					else:
						graph[i, j] = [[i - 1, j]]
			if j > 0:
				if m[i][j - 1] == '0':
					if (i, j) in graph:
						graph[i, j].append([i, j - 1])
					else:
						graph[i, j] = [[i, j - 1]]
			if i < n - 1:
				if m[i + 1][j] == '0':
					if (i, j) in graph:
						graph[i, j].append([i + 1, j])
					else:
						graph[i, j] = [[i + 1, j]]
			if j < n - 1:
				if m[i][j + 1] == '0':
					if (i, j) in graph:
						graph[i, j].append([i, j + 1])
					else:
						graph[i, j] = [[i, j + 1]]
			visited[i, j] = 0
			if (i, j) not in graph:
				graph[i, j] = []
temp1 = bfs((r1 - 1, c1 - 1))
temp2 = bfs((r2 - 1, c2 - 1))
m = 10000000
for i in temp1:
	for j in temp2:
		if (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2 < m:
			m = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
print(m)


import sys
sys.setrecursionlimit(10 ** 5 + 1)
inf = int(10 ** 20)
max_val = inf
min_val = -inf
RW = lambda : sys.stdin.readline().strip()
RI = lambda : int(RW())
RMI = lambda : [int(x) for x in sys.stdin.readline().strip().split()]
RWI = lambda : [x for x in sys.stdin.readline().strip().split()]
import sys
sys.setrecursionlimit(100000)
N = RI()
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
A = [[int(a) for a in input()] for i in range(N)]
X = [[0] * N for _ in range(N)]
L = []

def dfs(r, c):
	move = [[0, 1], [0, -1], [-1, 0], [1, 0]]
	X[r][c] = 1
	L.append((r, c))
	for m in move:
		(nr, nc) = (r + m[0], c + m[1])
		if nr >= 0 and nr < N and (nc >= 0) and (nc < N):
			if X[nr][nc] == 0 and A[nr][nc] == 0:
				dfs(nr, nc)
dfs(r1, c1)
if X[r2][c2]:
	print(0)
else:
	LL = [l for l in L]
	L = []
	dfs(r2, c2)
	mi = 10 ** 10
	for ll in LL:
		for l in L:
			mi = min((ll[0] - l[0]) ** 2 + (ll[1] - l[1]) ** 2, mi)
	print(mi)


import sys
sys.setrecursionlimit(10000)
invite = set()

def alice(i, j):
	total = [(i, j)]
	for (i, j) in total:
		if j - 1 >= 0 and planet[i][j - 1] == 0:
			planet[i][j - 1] = 1
			total.append((i, j - 1))
		if j + 1 <= n - 1 and planet[i][j + 1] == 0:
			planet[i][j + 1] = 1
			total.append((i, j + 1))
		if i - 1 >= 0 and planet[i - 1][j] == 0:
			planet[i - 1][j] = 1
			total.append((i - 1, j))
		if i + 1 <= n - 1 and planet[i + 1][j] == 0:
			planet[i + 1][j] = 1
			total.append((i + 1, j))
	return total
n = int(input())
start = [int(x) for x in input().split()]
end = [int(x) for x in input().split()]
planet = []
for i in range(n):
	line = [int(x) for x in list(input())]
	planet.append(line)
start_com = alice(start[0] - 1, start[1] - 1)
invite = set()
end_com = alice(end[0] - 1, end[1] - 1)
answer = 5000
for item in start_com:
	for element in end_com:
		answer = min(answer, (item[0] - element[0]) ** 2 + (item[1] - element[1]) ** 2)
print(answer)


import queue
n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
mat = [list(map(lambda x: x == '0', input())) for _ in range(n)]
dr = [-1, 0, 0, 1]
dc = [0, -1, 1, 0]

def dfs(u, vis):
	st = [u]
	vis[u[0]][u[1]] = True
	while len(st) > 0:
		(i, j) = st.pop()
		for k in range(len(dr)):
			i2 = i + dr[k]
			j2 = j + dc[k]
			if 0 <= i2 < n and 0 <= j2 < n and mat[i2][j2] and (not vis[i2][j2]):
				vis[i2][j2] = True
				st.append((i2, j2))
vis_src = [[False for _ in range(n)] for _ in range(n)]
vis_dst = [[False for _ in range(n)] for _ in range(n)]
dfs((r1, c1), vis_src)
dfs((r2, c2), vis_dst)
ans = 10 ** 9
for i in range(n):
	for j in range(n):
		for i2 in range(n):
			for j2 in range(n):
				if vis_src[i][j] and vis_dst[i2][j2]:
					curr = (i - i2) ** 2 + (j - j2) ** 2
					ans = min(ans, curr)
print(ans)


import sys
from collections import defaultdict as dd
from itertools import permutations as pp
from itertools import combinations as cc
from collections import Counter as ccd
from random import randint as rd
from bisect import bisect_left as bl
import heapq
mod = 10 ** 9 + 7

def ri(flag=0):
	if flag == 0:
		return [int(i) for i in sys.stdin.readline().split()]
	else:
		return int(sys.stdin.readline())

def valid(i, j):
	if i < 0 or i >= n:
		return 0
	if j < 0 or j >= n:
		return 0
	if vis[i][j] == 1 or mat[i][j] == '1':
		return 0
	return 1
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]

def bfs(i, j):
	one = [(i, j)]
	vis[i][j] = 1
	s = [(i, j)]
	while s:
		(x, y) = s.pop(-1)
		for k in range(4):
			if valid(x + dx[k], y + dy[k]):
				vis[x + dx[k]][y + dy[k]] = 1
				s.append((x + dx[k], y + dy[k]))
				one.append((x + dx[k], y + dy[k]))
	return one
n = ri(1)
(x1, y1) = [int(i) - 1 for i in input().split()]
(x2, y2) = [int(i) - 1 for i in input().split()]
mat = []
vis = [[0 for i in range(n)] for j in range(n)]
for i in range(n):
	mat.append(list(input()))
one = bfs(x1, y1)
two = bfs(x2, y2)
ans = 999999999999
for (i, j) in one:
	for (p, q) in two:
		ans = min(ans, (i - p) ** 2 + (j - q) ** 2)
print(ans)


from sys import setrecursionlimit
setrecursionlimit(10 ** 9)
n = int(input())
(r1, c1) = [int(i) for i in input().split()]
(r2, c2) = [int(i) for i in input().split()]
MAP = [[int(s) for s in input()] for i in range(n)]
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1

def dfs(r, c, mark, A):
	if r < 0 or r >= n or c < 0 or (c >= n):
		return
	if MAP[r][c] == 1:
		return
	if MAP[r][c] == mark:
		return
	A.append((r, c))
	MAP[r][c] = mark
	for (dr, dc) in ((0, 1), (0, -1), (1, 0), (-1, 0)):
		dfs(r + dr, c + dc, mark, A)
A = []
dfs(r1, c1, 2, A)
if MAP[r1][c1] == MAP[r2][c2]:
	print(0)
	exit()
B = []
dfs(r2, c2, 3, B)
ans = 2 * n ** 2
for (a, b) in A:
	ans = min(ans, min(((a - c) ** 2 + (b - d) ** 2 for (c, d) in B)))
print(ans)


import sys
sys.setrecursionlimit(100000)
n = int(input())
v = []
for i in range(n + 1):
	v.append([0] * (n + 1))

def dfs(sti, stj, v, d1, i, j, s):
	v[sti][stj] = 1
	if (i, j) not in d1:
		d1[i, j] = [(sti, stj)]
	else:
		d1[i, j].append((sti, stj))
	if sti - 1 > 0 and v[sti - 1][stj] == 0 and (s[sti - 1][stj] == '0'):
		dfs(sti - 1, stj, v, d1, i, j, s)
	if stj + 1 <= n and v[sti][stj + 1] == 0 and (s[sti][stj + 1] == '0'):
		dfs(sti, stj + 1, v, d1, i, j, s)
	if stj - 1 > 0 and v[sti][stj - 1] == 0 and (s[sti][stj - 1] == '0'):
		dfs(sti, stj - 1, v, d1, i, j, s)
	if sti + 1 <= n and v[sti + 1][stj] == 0 and (s[sti + 1][stj] == '0'):
		dfs(sti + 1, stj, v, d1, i, j, s)
(a, b) = map(int, input().split())
(c, d) = map(int, input().split())
s = ['0' * (n + 1)]
for i in range(n):
	s.append('0' + input())
d1 = {}
try:
	dfs(a, b, v, d1, a, b, s)
	dfs(c, d, v, d1, c, d, s)
except:
	print(0)
mi = 10 ** 9
for i in d1[a, b]:
	for j in d1[c, d]:
		dis = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
		if dis < mi:
			mi = dis
print(mi)


import queue

def bfs(i, j, tipo):
	fila = queue.Queue()
	fila.put((i, j))
	vis[i][j] = True
	if tipo == 1:
		terradela.add((i, j))
	else:
		terradoponto.add((i, j))
	while not fila.empty():
		elemento = fila.get()
		for k in range(2):
			for l in range(-1, 2):
				x3 = elemento[0]
				y3 = elemento[1]
				if k == 0:
					y3 += l
				else:
					x3 += l
				if grid[x3][y3] == '0' and (not vis[x3][y3]):
					vis[x3][y3] = True
					fila.put((x3, y3))
					if tipo == 1:
						terradela.add((x3, y3))
					else:
						terradoponto.add((x3, y3))
m = int(input())
grid = [['1' for j in range(m + 2)] for i in range(m + 2)]
vis = [[False for j in range(m + 2)] for i in range(m + 2)]
terradela = set()
terradoponto = set()
resultados = []
(x1, y1) = map(int, input().split())
(x2, y2) = map(int, input().split())
for i in range(1, m + 1):
	linha = input()
	for j in range(1, m + 1):
		grid[i][j] = linha[j - 1]
bfs(x1, y1, 1)
if (x2, y2) in terradela:
	print(0)
else:
	bfs(x2, y2, 2)
	for i in terradela:
		for j in terradoponto:
			resultados.append((i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
	print(min(resultados))


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
world = []
world.append('1' * (n + 2))
for i in range(n):
	world.append('1' + input() + '1')
world.append('1' * (n + 2))

def valid_neighbors(cell):
	neighbors = []
	(x, y) = cell
	if world[x - 1][y] == '0':
		neighbors.append((x - 1, y))
	if world[x + 1][y] == '0':
		neighbors.append((x + 1, y))
	if world[x][y - 1] == '0':
		neighbors.append((x, y - 1))
	if world[x][y + 1] == '0':
		neighbors.append((x, y + 1))
	return neighbors

def explore(cell, visited):
	visited.add(cell)
	for neighbor in valid_neighbors(cell):
		if neighbor not in visited:
			explore(neighbor, visited)

def dist(source, dest):
	return int(pow(source[0] - dest[0], 2) + pow(source[1] - dest[1], 2))
visited1 = set()
explore((r1, c1), visited1)
if (r2, c2) in visited1:
	print(0)
else:
	visited2 = set()
	explore((r2, c2), visited2)
	ans = float('inf')
	for source in visited1:
		for dest in visited2:
			ans = min(ans, dist(source, dest))
	print(ans)


import sys, queue
n = int(sys.stdin.readline())
(r1, c1) = map(int, sys.stdin.readline().split())
(r2, c2) = map(int, sys.stdin.readline().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
ls = []
rs = []
grid = []
for i in range(n):
	grid.append(list(map(int, list(sys.stdin.readline().strip()))))
q = queue.Queue()
q.put((r1, c1))
while not q.empty():
	no = q.get()
	x = no[0]
	y = no[1]
	if x == r2 and y == c2:
		print(0)
		sys.exit()
	ls.append((x, y))
	for i in range(-1, 2):
		for j in range(-1, 2):
			if not (i * j == 0 and i + j != 0):
				continue
			if not (x + i >= 0 and x + i < n and (y + j >= 0) and (y + j < n)):
				continue
			xn = x + i
			yn = y + j
			if grid[xn][yn] == 0:
				q.put((xn, yn))
				grid[xn][yn] = 2
q = queue.Queue()
q.put((r2, c2))
while not q.empty():
	no = q.get()
	x = no[0]
	y = no[1]
	rs.append((x, y))
	for i in range(-1, 2):
		for j in range(-1, 2):
			if not (i * j == 0 and i + j != 0):
				continue
			if not (x + i >= 0 and x + i < n and (y + j >= 0) and (y + j < n)):
				continue
			xn = x + i
			yn = y + j
			if grid[xn][yn] == 0:
				q.put((xn, yn))
				grid[xn][yn] = 2
cost = 1000000000
for l in ls:
	for r in rs:
		c = abs(l[0] - r[0]) ** 2 + abs(l[1] - r[1]) ** 2
		cost = min(cost, c)
print(cost)


class DisjointSet:

	def __init__(self, n):
		self.num_sets = n
		self.parents = list(range(n))
		self.ranks = [0] * n
		self.sizes = [1] * n

	def find(self, j):
		while self.parents[j] != j:
			j = self.parents[j]
		return j

	def union(self, i, j):
		i = self.find(i)
		j = self.find(j)
		if i == j:
			return False
		rd = self.ranks[i] - self.ranks[j]
		if rd == 0:
			self.ranks[i] += 1
		elif rd < 0:
			(i, j) = (j, i)
		self.parents[j] = i
		self.sizes[i] += self.sizes[j]
		self.sizes[j] = 0
		self.num_sets -= 1
		return True

def main():
	n = int(input())
	n2 = n * n
	p1 = list(map(int, input().split()))
	p2 = list(map(int, input().split()))
	ll = [c == '0' for c in ''.join([input() for _ in range(n)])]
	dsu = DisjointSet(n2)
	for i in range(n2):
		if ll[i]:
			if i >= 1 and i % n > 0 and ll[i - 1]:
				dsu.union(i, i - 1)
			if i >= n and ll[i - n]:
				dsu.union(i, i - n)
	r1 = dsu.find((p1[0] - 1) * n + p1[1] - 1)
	r2 = dsu.find((p2[0] - 1) * n + p2[1] - 1)
	mc = 2 * n2
	l1 = []
	l2 = []
	for i in range(n2):
		if ll[i] and (not (i >= 1 and i % n > 0 and ll[i - 1] and (i >= n) and ll[i - n] and (i % n != n - 1) and ll[i + 1] and (i + n < n2) and ll[i + n])):
			if dsu.find(i) == r1:
				l1.append((i // n, i % n))
			if dsu.find(i) == r2:
				l2.append((i // n, i % n))
	for (x1, y1) in l1:
		for (x2, y2) in l2:
			cost = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
			if cost < mc:
				mc = cost
	print(mc)
main()


def can_find(i, j, land, target_i, target_j):
	res = False
	land.append((i, j))
	if i == target_i and j == target_j:
		return True
	for (new_i, new_j) in [(i + 1, j), (i - 1, j), (i, j - 1), (i, j + 1)]:
		if 0 <= new_i < rows and 0 <= new_j < rows and ((new_i, new_j) not in seen) and (board[new_i][new_j] == 0):
			seen.add((new_i, new_j))
			res = can_find(new_i, new_j, land, target_i, target_j)
	return res

def cost(a, b):
	return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2
rows = int(input())
(i, j) = map(lambda x: int(x) - 1, input().split())
(target_i, target_j) = map(lambda x: int(x) - 1, input().split())
seen = set()
seen.add((i, j))
board = []
land = []
for _ in range(rows):
	row = input()
	board.append([int(i) for i in row])
if can_find(i, j, land, target_i, target_j):
	print(0)
else:
	res = float('inf')
	water = []
	can_find(target_i, target_j, water, i, j)
	for l in land:
		for w in water:
			res = min(res, cost(l, w))
	print(res)


def dis(u, v):
	(x1, y1) = u
	(x2, y2) = v
	return (x1 - x2) ** 2 + (y1 - y2) ** 2

def adj(u):
	(x, y) = u
	t = []
	if x + 1 < n and a[x + 1][y] == '0':
		t.append([x + 1, y])
	if y + 1 < n and a[x][y + 1] == '0':
		t.append([x, y + 1])
	if x - 1 >= 0 and a[x - 1][y] == '0':
		t.append([x - 1, y])
	if y - 1 >= 0 and a[x][y - 1] == '0':
		t.append([x, y - 1])
	return t

def bfs(s):
	ans = [s]
	(x, y) = s
	v2[x][y] = 1
	frontier = [s]
	while frontier:
		nex = []
		for u in frontier:
			for v in adj(u):
				if v2[v[0]][v[1]] == 0:
					nex.append(v)
					v2[v[0]][v[1]] = 1
					ans.append(v)
		frontier = nex
	return ans
n = int(input())
(r1, c1) = [int(i) for i in input().split(' ')]
(r2, c2) = [int(i) for i in input().split(' ')]
a = []
for i in range(n):
	a.append(list(input()))
v2 = [[0 for i in range(n)] for j in range(n)]
ans1 = bfs([r1 - 1, c1 - 1])
ans2 = bfs([r2 - 1, c2 - 1])
r = 9999999999
for i in ans1:
	for j in ans2:
		r = min(r, dis(i, j))
print(r)


from queue import *

def ff(r, c):
	seq = Queue()
	seq.put((r, c))
	while not seq.empty():
		(r, c) = seq.get()
		for x in range(4):
			if x == 0:
				i = 1
				j = 0
			elif x == 1:
				i = 0
				j = 1
			elif x == 2:
				i = -1
				j = 0
			else:
				i = 0
				j = -1
			if 0 <= r + i < n and 0 <= c + j < n:
				if grid[r + i][c + j] == 0:
					seq.put((r + i, c + j))
					grid[r + i][c + j] = 2
				else:
					pinggir1.add((r, c))

def ff2(r, c):
	seq = Queue()
	seq.put((r, c))
	while not seq.empty():
		(r, c) = seq.get()
		for x in range(4):
			if x == 0:
				i = 1
				j = 0
			elif x == 1:
				i = 0
				j = 1
			elif x == 2:
				i = -1
				j = 0
			else:
				i = 0
				j = -1
			if 0 <= r + i < n and 0 <= c + j < n:
				if grid[r + i][c + j] == 0:
					seq.put((r + i, c + j))
					grid[r + i][c + j] = 2
				else:
					pinggir2.add((r, c))
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
grid = []
for i in range(n):
	grid.append(list(map(int, input().strip())))
pinggir1 = {(r1, c1)}
ff(r1, c1)
pinggir2 = {(r2, c2)}
ff2(r2, c2)
ans = 10000
for i in pinggir1:
	for j in pinggir2:
		ans = min(ans, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(ans)


import bisect
import decimal
from decimal import Decimal
import os
from collections import Counter
import bisect
from collections import defaultdict
import math
import random
import heapq
from math import sqrt
import sys
from functools import reduce, cmp_to_key
from collections import deque
import threading
from itertools import combinations
from io import BytesIO, IOBase
from itertools import accumulate
mod = 10 ** 9 + 7
decimal.getcontext().prec = 46

def primeFactors(n):
	prime = set()
	while n % 2 == 0:
		prime.add(2)
		n = n // 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			prime.add(i)
			n = n // i
	if n > 2:
		prime.add(n)
	return list(prime)

def getFactors(n):
	factors = []
	i = 1
	while i <= math.sqrt(n):
		if n % i == 0:
			if n // i == i:
				factors.append(i)
			else:
				factors.append(i)
				factors.append(n // i)
		i = i + 1
	return factors

def modefiedSieve():
	mx = 10 ** 7 + 1
	sieve = [-1] * mx
	for i in range(2, mx):
		if sieve[i] == -1:
			sieve[i] = i
			for j in range(i * i, mx, i):
				if sieve[j] == -1:
					sieve[j] = i
	return sieve

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	num = []
	for p in range(2, n + 1):
		if prime[p]:
			num.append(p)
	return num

def lcm(a, b):
	return a * b // math.gcd(a, b)

def sort_dict(key_value):
	return sorted(key_value.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)

def list_input():
	return list(map(int, input().split()))

def num_input():
	return map(int, input().split())

def string_list():
	return list(input())

def decimalToBinary(n):
	return bin(n).replace('0b', '')

def binaryToDecimal(n):
	return int(n, 2)

def DFS(n, adj, s):
	visited = [False for i in range(n + 1)]
	stack = []
	stack.append(s)
	while len(stack):
		s = stack[-1]
		stack.pop()
		if not visited[s]:
			visited[s] = True
		for node in adj[s]:
			if not visited[node]:
				stack.append(node)

def BFS(n, mat, sx, sy, ex, ey):
	visited = [[False] * n for i in range(n)]
	queue = [(sx, sy)]
	points = []
	while queue != []:
		(u, v) = queue.pop(0)
		if (u, v) == (ex, ey):
			return 0
		points.append((u, v))
		if u - 1 >= 0 and mat[u - 1][v] == '0' and (not visited[u - 1][v]):
			visited[u - 1][v] = True
			queue.append((u - 1, v))
		if u + 1 < n and mat[u + 1][v] == '0' and (not visited[u + 1][v]):
			visited[u + 1][v] = True
			queue.append((u + 1, v))
		if v - 1 >= 0 and mat[u][v - 1] == '0' and (not visited[u][v - 1]):
			visited[u][v - 1] = True
			queue.append((u, v - 1))
		if v + 1 < n and mat[u][v + 1] == '0' and (not visited[u][v + 1]):
			visited[u][v + 1] = True
			queue.append((u, v + 1))
	return points

def maxSubArraySum(a, size):
	max_so_far = -sys.maxsize - 1
	max_ending_here = 0
	start = 0
	end = 0
	s = 0
	for i in range(0, size):
		max_ending_here += a[i]
		if max_so_far < max_ending_here:
			max_so_far = max_ending_here
			start = s
			end = i
		if max_ending_here < 0:
			max_ending_here = 0
			s = i + 1
	return (max_so_far, start, end)

def lis(arr):
	n = len(arr)
	lis = [1] * n
	for i in range(1, n):
		for j in range(0, i):
			if arr[i] >= arr[j] and lis[i] < lis[j] + 1:
				lis[i] = lis[j] + 1
	maximum = 0
	for i in range(n):
		maximum = max(maximum, lis[i])
	return maximum

def solve():
	n = int(input())
	(sx, sy) = num_input()
	(sx, sy) = (sx - 1, sy - 1)
	(ex, ey) = num_input()
	(ex, ey) = (ex - 1, ey - 1)
	mat = []
	for _ in range(n):
		mat.append(list(input()))
	start_points = BFS(n, mat, sx, sy, ex, ey)
	if start_points == 0:
		print(0)
		return
	end_points = BFS(n, mat, ex, ey, sx, sy)
	dist = 10 ** 10
	for (u, v) in start_points:
		for (x, y) in end_points:
			dist = min(dist, (u - x) ** 2 + (v - y) ** 2)
	print(dist)
t = 1
for _ in range(t):
	solve()


n = int(input())
(r1, c1) = [int(i) for i in input().split(' ')]
(r2, c2) = [int(i) for i in input().split(' ')]
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
m = [[int(i) for i in input()] for _ in range(n)]

def is_inside(i, j):
	if 0 <= i and i < n and (0 <= j) and (j < n):
		return True
	return False
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

def explore_island(x, y):
	island = [(x, y)]
	for (x1, y1) in island:
		for (x2, y2) in directions:
			(r, c) = (x1 + x2, y1 + y2)
			if is_inside(r, c) and m[r][c] == 0:
				m[r][c] = 1
				island.append((r, c))
	return island

def distance(a, b):
	return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2
island_1 = explore_island(r1, c1)
if m[r2][c2] == 1:
	print(0)
else:
	island_2 = explore_island(r2, c2)
	m = float('inf')
	for i in island_1:
		for j in island_2:
			m = min(m, distance(i, j))
	print(m)


import sys
from bisect import bisect_left, bisect_right, insort
from collections import deque, Counter
from math import gcd, sqrt, factorial, ceil, log10, log2, floor
from itertools import permutations
from heapq import heappush, heappop, heapify
inf = float('inf')
mod = 1000000007
sys.setrecursionlimit(10 ** 9)

def factorial_p(n, p):
	ans = 1
	if n <= p // 2:
		for i in range(1, n + 1):
			ans = ans * i % p
	else:
		for i in range(1, p - n):
			ans = ans * i % p
		ans = pow(ans, p - 2, p)
		if n % 2 == 0:
			ans = p - ans
	return ans

def nCr_p(n, r, p):
	ans = 1
	while n != 0 or r != 0:
		(a, b) = (n % p, r % p)
		if a < b:
			return 0
		ans = ans * factorial_p(a, p) * pow(factorial_p(b, p), p - 2, p) * pow(factorial_p(a - b, p), p - 2, p) % p
		n //= p
		r //= p
	return ans

def prime_sieve(n):
	flag = n % 6 == 2
	sieve = bytearray((n // 3 + flag >> 3) + 1)
	for i in range(1, int(n ** 0.5) // 3 + 1):
		if not sieve[i >> 3] >> (i & 7) & 1:
			k = 3 * i + 1 | 1
			for j in range(k * k // 3, n // 3 + flag, 2 * k):
				sieve[j >> 3] |= 1 << (j & 7)
			for j in range(k * (k - 2 * (i & 1) + 4) // 3, n // 3 + flag, 2 * k):
				sieve[j >> 3] |= 1 << (j & 7)
	return sieve

def prime_list(n):
	res = []
	if n > 1:
		res.append(2)
	if n > 2:
		res.append(3)
	if n > 4:
		sieve = prime_sieve(n + 1)
		res.extend((3 * i + 1 | 1 for i in range(1, (n + 1) // 3 + (n % 6 == 1)) if not sieve[i >> 3] >> (i & 7) & 1))
	return res

def is_prime(n):
	if n < 5 or n & 1 == 0 or n % 3 == 0:
		return 2 <= n <= 3
	s = (n - 1 & 1 - n).bit_length() - 1
	d = n >> s
	for a in [2, 325, 9375, 28178, 450775, 9780504, 1795265022]:
		p = pow(a, d, n)
		if p == 1 or p == n - 1 or a % n == 0:
			continue
		for _ in range(s):
			p = p * p % n
			if p == n - 1:
				break
		else:
			return False
	return True

def all_factors(n):
	(small, large) = ([], [])
	for i in range(1, int(n ** 0.5) + 1, 2 if n & 1 else 1):
		if not n % i:
			small.append(i)
			large.append(n // i)
	if small[-1] == large[-1]:
		large.pop()
	large.reverse()
	small.extend(large)
	return small

def dfs(r, c, mark, A):
	if r < 0 or r >= n or c < 0 or (c >= n):
		return
	if mat[r][c] == 1:
		return
	if mat[r][c] == mark:
		return
	mat[r][c] = mark
	A.append((r, c))
	for (x, y) in ((0, 1), (1, 0), (-1, 0), (0, -1)):
		dfs(r + x, c + y, mark, A)

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def input():
	return sys.stdin.readline().strip()
n = int(input())
(r1, c1) = get_ints()
(r2, c2) = get_ints()
mat = []
for i in range(n):
	string = input()
	lst = [int(i) for i in string]
	mat.append(lst)
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
A = []
dfs(r1, c1, 2, A)
if mat[r2][c2] == 2:
	print(0)
	exit()
B = []
dfs(r2, c2, 3, B)
ans = 2 * n ** 2
for (x, y) in A:
	for (m, n) in B:
		ans = min(ans, (m - x) ** 2 + (n - y) ** 2)
print(ans)


from copy import deepcopy
n = int(input())
start = list(map(int, input().split()))
start = (start[0] - 1, start[1] - 1)
end = list(map(int, input().split()))
end = (end[0] - 1, end[1] - 1)
field = []
for _ in range(n):
	field.append(list(map(lambda x: not bool(int(x)), input())))
from_start = [[False] * n for _ in range(n)]
from_end = [[False] * n for _ in range(n)]

def find(m, i, j):
	stack = [(i, j)]
	while stack:
		el = stack.pop()
		i = el[0]
		j = el[1]
		m[i][j] = True
		if i > 0 and (not m[i - 1][j]) and field[i - 1][j]:
			stack.append((i - 1, j))
		if j > 0 and (not m[i][j - 1]) and field[i][j - 1]:
			stack.append((i, j - 1))
		if j < n - 1 and (not m[i][j + 1]) and field[i][j + 1]:
			stack.append((i, j + 1))
		if i < n - 1 and (not m[i + 1][j]) and field[i + 1][j]:
			stack.append((i + 1, j))
find(from_start, start[0], start[1])
find(from_end, end[0], end[1])
if from_start[end[0]][end[1]]:
	print(0)
	exit()
m = 2 * n * n
for i in range(n):
	for j in range(n):
		if from_start[i][j]:
			for k in range(n):
				for l in range(n):
					if from_end[k][l]:
						cost = (k - i) ** 2 + (l - j) ** 2
						if cost < m:
							m = cost
print(m)


import sys
sys.setrecursionlimit(10 ** 6)
inf = float('inf')
mod = 1000000007

def get_array():
	return list(map(int, sys.stdin.readline().split()))

def get_ints():
	return map(int, sys.stdin.readline().split())

def input():
	return sys.stdin.readline()

def dis(x1, y1, x2, y2):
	return pow(x1 - x2, 2) + pow(y1 - y2, 2)

def check(i, j):
	if i >= 0 and i < n and (j >= 0) and (j < n):
		return True
	return False

def neighbours(i, j):
	arr = [[i, j - 1], [i, j + 1], [i - 1, j], [i + 1, j]]
	return arr

def dfs(x, y):
	visited[x][y] = True
	for p in neighbours(x, y):
		(u, v) = (p[0], p[1])
		if check(u, v) == True and visited[u][v] == False and (matrix[u][v] == '0'):
			if cnt == 0:
				first.append((u, v))
			else:
				second.append((u, v))
			dfs(u, v)

def main():
	global n, r1, r2, c1, c2, matrix, visited, first, second, cnt
	cnt = 0
	first = []
	second = []
	n = int(input())
	(r1, c1) = get_ints()
	r1 -= 1
	c1 -= 1
	(r2, c2) = get_ints()
	r2 -= 1
	c2 -= 1
	matrix = [0 for _ in range(n)]
	for i in range(n):
		matrix[i] = input().strip()
	visited = [[False] * n for _ in range(n)]
	first.append((r1, c1))
	dfs(r1, c1)
	cnt += 1
	if visited[r2][c2] == True:
		print(0)
		return
	second.append((r2, c2))
	dfs(r2, c2)
	mn = inf
	for i in first:
		for j in second:
			mn = min(mn, dis(*i, *j))
	print(mn)
main()


class Pair:

	def __init__(self, x, y):
		self.x = x
		self.y = y
fileReader = None

def getInt():
	if fileReader is None:
		return int(input())
	else:
		return int(fileReader.readline())

def getList():
	if fileReader is None:
		return list(map(int, input().split(' ')))
	else:
		return list(map(int, fileReader.readline().split(' ')))

def getString():
	if fileReader is None:
		return input()
	else:
		return fileReader.readline()
n = getInt()
(r1, c1) = getList()
(r2, c2) = getList()
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
data = []
for i in range(n):
	data.append(getString())
visit = [[False] * n for i in range(n)]
rst = []
plant = [[r1, c1]]
while len(plant) > 0:
	(rx, cx) = plant.pop()
	if visit[rx][cx]:
		continue
	visit[rx][cx] = True
	b = False
	if rx + 1 < n:
		if data[rx + 1][cx] == '1':
			b = True
		else:
			plant.append([rx + 1, cx])
	if rx - 1 >= 0:
		if data[rx - 1][cx] == '1':
			b = True
		else:
			plant.append([rx - 1, cx])
	if cx + 1 < n:
		if data[rx][cx + 1] == '1':
			b = True
		else:
			plant.append([rx, cx + 1])
	if cx - 1 >= 0:
		if data[rx][cx - 1] == '1':
			b = True
		else:
			plant.append([rx, cx - 1])
	if b:
		rst.append([rx, cx])
plant = [[r2, c2]]
sst = []
while len(plant) > 0:
	b = False
	(rx, cx) = plant.pop()
	if visit[rx][cx]:
		continue
	visit[rx][cx] = True
	if rx + 1 < n:
		if data[rx + 1][cx] == '1':
			b = True
		else:
			plant.append([rx + 1, cx])
	if rx - 1 >= 0:
		if data[rx - 1][cx] == '1':
			b = True
		else:
			plant.append([rx - 1, cx])
	if cx + 1 < n:
		if data[rx][cx + 1] == '1':
			b = True
		else:
			plant.append([rx, cx + 1])
	if cx - 1 >= 0:
		if data[rx][cx - 1] == '1':
			b = True
		else:
			plant.append([rx, cx - 1])
	if b:
		sst.append([rx, cx])
c = 1000010101
for p in rst:
	for q in sst:
		c = min(c, (p[0] - q[0]) ** 2 + (p[1] - q[1]) ** 2)
if c == 1000010101:
	print(0)
else:
	print(c)
if fileReader is not None:
	fileReader.close()


import sys
sys.setrecursionlimit(15000)
n = int(input())
se1 = set()
se2 = set()
(a, b) = map(int, input().split())
(x, y) = map(int, input().split())
lis = []
for i in range(n):
	lis.append(input())

def dfs(x, y, f):
	if x < 0 or y < 0 or x >= len(lis) or (y >= len(lis[0])) or (lis[x][y] == '1'):
		return
	if f == 0:
		if (x, y) in se1:
			return
		se1.add((x, y))
	else:
		if (x, y) in se2:
			return
		se2.add((x, y))
	dfs(x - 1, y, f)
	dfs(x + 1, y, f)
	dfs(x, y - 1, f)
	dfs(x, y + 1, f)
dfs(a - 1, b - 1, 0)
dfs(x - 1, y - 1, 1)
ans = float('Inf')
for i in se1:
	if i in se2:
		print(0)
		exit()
	for j in se2:
		ans = min(ans, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(ans)


def reach(x, y, matrix):
	res = set()
	res.add((x, y))
	frontier = set()
	isFirst = True
	if x - 1 >= 0 and matrix[x - 1][y] == 0:
		frontier.add((x - 1, y))
		res.add((x - 1, y))
	if x + 1 < len(matrix) and matrix[x + 1][y] == 0:
		frontier.add((x + 1, y))
		res.add((x + 1, y))
	if y - 1 >= 0 and matrix[x][y - 1] == 0:
		frontier.add((x, y - 1))
		res.add((x, y - 1))
	if y + 1 < len(matrix) and matrix[x][y + 1] == 0:
		frontier.add((x, y + 1))
		res.add((x, y + 1))
	while len(frontier) > 0:
		toConsider = frontier.pop()
		x = toConsider[0]
		y = toConsider[1]
		if x - 1 >= 0 and matrix[x - 1][y] == 0 and ((x - 1, y) not in res):
			frontier.add((x - 1, y))
			res.add((x - 1, y))
		if x + 1 < len(matrix) and matrix[x + 1][y] == 0 and ((x + 1, y) not in res):
			frontier.add((x + 1, y))
			res.add((x + 1, y))
		if y - 1 >= 0 and matrix[x][y - 1] == 0 and ((x, y - 1) not in res):
			frontier.add((x, y - 1))
			res.add((x, y - 1))
		if y + 1 < len(matrix) and matrix[x][y + 1] == 0 and ((x, y + 1) not in res):
			frontier.add((x, y + 1))
			res.add((x, y + 1))
	return res

def cost(t1, t2):
	return (t1[0] - t2[0]) ** 2 + (t1[1] - t2[1]) ** 2
size = int(input())
start = input().split(' ')
end = input().split(' ')
matrix = []
for i in range(0, size):
	toInsert = []
	data = input()
	for c in data:
		toInsert.append(int(c))
	matrix.append(toInsert)
fromStart = reach(int(start[0]) - 1, int(start[1]) - 1, matrix)
fromEnd = reach(int(end[0]) - 1, int(end[1]) - 1, matrix)
res = -1
calculated = set()
if len(fromStart.intersection(fromEnd)) > 0:
	print(0)
else:
	for s in fromStart:
		for e in fromEnd:
			if (s, e) not in calculated:
				c = cost(s, e)
				calculated.add((s, e))
				calculated.add(((s[1], s[0]), (e[1], e[0])))
				if res == -1 or c < res:
					res = c
	print(res)


def bfs(sx, sy, vis, grid):
	points = [[0, 1], [0, -1], [1, 0], [-1, 0]]
	q = [[sx, sy]]
	vis[sx][sy] = 0
	while q:
		(x, y) = q[0]
		q.pop(0)
		for (ptx, pty) in points:
			if x + ptx >= 0 and y + pty >= 0 and (x + ptx < len(grid)) and (y + pty < len(grid[0])) and (vis[x + ptx][y + pty] == -1) and (grid[x + ptx][y + pty] == 0):
				q = q + [[x + ptx, y + pty]]
				vis[ptx + x][pty + y] = vis[x][y] + 1
	return vis

def dist(a, b):
	return pow(a[0] - b[0], 2) + pow(a[1] - b[1], 2)

def togo(arr, start, end, n):
	portal = []
	(vis1, vis2) = ([[-1] * len(arr[0]) for i in range(len(arr))], [[-1] * len(arr[0]) for i in range(len(arr))])
	vis1 = bfs(start[0] - 1, start[1] - 1, vis1, arr)
	vis2 = bfs(end[0] - 1, end[1] - 1, vis2, arr)
	(d1, d2) = ([], [])
	for i in range(n):
		for j in range(n):
			if vis1[i][j] != -1:
				d1.append((i, j))
			if vis2[i][j] != -1:
				d2.append((i, j))
	ans = []
	for p1 in d1:
		for p2 in d2:
			ans.append(dist(p1, p2))
	return min(ans)
n = int(input())
start = list(map(int, input().strip().split()))
end = list(map(int, input().strip().split()))
ar = []
for i in range(n):
	lst = list(input())
	lst = list(map(int, lst))
	ar.append(lst)
print(togo(ar, start, end, n))


import sys
try:
	n = int(input())
	r1 = tuple(map(lambda c: int(c) - 1, input().split()))
	r2 = tuple(map(lambda c: int(c) - 1, input().split()))
	m = [[*map(int, input())] for _ in range(n)]
except:
	print('oopsie1')

def adj(i, j):
	l = []
	if i > 0:
		l.append((i - 1, j))
	if i < n - 1:
		l.append((i + 1, j))
	if j > 0:
		l.append((i, j - 1))
	if j < n - 1:
		l.append((i, j + 1))
	return l
seen = set()

def dfs(i, j):
	sys.setrecursionlimit(sys.getrecursionlimit() + 1)
	try:
		seen.add((i, j))
		res = [(i, j)]
		for (x, y) in adj(i, j):
			if (x, y) not in seen and m[x][y] == 0:
				t = dfs(x, y)
				res.extend(t)
		return res
	except Exception as e:
		print(e)
c1 = dfs(r1[0], r1[1])
res = float('inf')
if r2 in seen:
	res = 0
else:
	c2 = dfs(r2[0], r2[1])
	try:
		for x1 in c1:
			for x2 in c2:
				v = (x1[0] - x2[0]) ** 2 + (x1[1] - x2[1]) ** 2
				res = min(res, v)
	except:
		print('oopsie3')
print(res)


import sys
import math
from collections import deque
DIFF = [(0, 1), (1, 0), (-1, 0), (0, -1)]

def search(n, start, a, colors):
	borders = []
	q = deque([start])
	while q:
		(x, y) = q.popleft()
		is_border = False
		for (dx, dy) in DIFF:
			(new_x, new_y) = (x + dx, y + dy)
			if not 0 <= new_x < n:
				continue
			if not 0 <= new_y < n:
				continue
			if a[new_x][new_y] == '0' and colors[new_x][new_y] == 0:
				q.append((new_x, new_y))
				colors[new_x][new_y] = colors[x][y]
			elif a[new_x][new_y] == '1':
				is_border = True
		if is_border:
			borders.append((x, y))
	return borders

def solve(n, p1, p2, a):
	(r1, c1) = p1
	(r2, c2) = p2
	colors = [[0] * n for _ in range(n)]
	colors[r1][c1] = 1
	borders_1 = search(n, p1, a, colors)
	if colors[r2][c2] == colors[r1][c1]:
		return 0
	colors[r2][c2] = 2
	borders_2 = search(n, p2, a, colors)
	ans = float('inf')
	for (x1, y1) in borders_1:
		for (x2, y2) in borders_2:
			ans = min((x1 - x2) ** 2 + (y1 - y2) ** 2, ans)
	return ans
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
p1 = (r1 - 1, c1 - 1)
p2 = (r2 - 1, c2 - 1)
a = []
for _ in range(n):
	a.append(list(input()))
print(solve(n, p1, p2, a))


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

def dfs(l, start, A, n):
	DIR = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	q = deque([start])
	visit = [[False for i in range(n)] for j in range(n)]
	while q:
		(x, y) = q.popleft()
		visit[x][y] = True
		A.append((x, y))
		for i in range(4):
			(a, b) = DIR[i]
			if x + a > -1 and x + a < n and (b + y > -1) and (b + y < n) and (l[x + a][y + b] != '1') and (visit[x + a][y + b] == False):
				q.appendleft((x + a, y + b))
	return

def check(a, b):
	return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2

def main():
	try:
		n = I()
		start = list(In())
		end = list(In())
		start[0] -= 1
		start[1] -= 1
		end[0] -= 1
		end[1] -= 1
		l = []
		for i in range(n):
			l.append(Sn())
		(A, B) = ([], [])
		dfs(l, start, A, n)
		dfs(l, end, B, n)
		ans = P
		for x in A:
			for y in B:
				ans = min(check(x, y), ans)
		print(ans)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		groups = {r: [] for r in self.roots()}
		for i in range(self.N):
			groups[self.find(i)].append(i)
		return groups

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
n = int(input())
(r1, c1) = map(int, input().split())
r1 -= 1
c1 -= 1
(r2, c2) = map(int, input().split())
r2 -= 1
c2 -= 1
grid = []
for i in range(n):
	grid.append(input())
uf = UnionFind(n * n)
for i in range(n):
	for j in range(n):
		if i < n - 1 and grid[i][j] == '0' and (grid[i + 1][j] == '0'):
			uf.union(i * n + j, (i + 1) * n + j)
		if j < n - 1 and grid[i][j] == '0' and (grid[i][j + 1] == '0'):
			uf.union(i * n + j, i * n + j + 1)
if uf.same(r1 * n + c1, r2 * n + c2):
	print(0)
	exit()
ans = 10 ** 18
for x1 in range(n):
	for y1 in range(n):
		for x2 in range(n):
			for y2 in range(n):
				if uf.same(x1 * n + y1, r1 * n + c1) and uf.same(x2 * n + y2, r2 * n + c2):
					ans = min(ans, (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
print(ans)


class UnionFind:

	def __init__(self, par):
		self.par = par
		self.rank = {}
		for p in par.keys():
			self.rank[p] = 1

	def union(self, x, y):
		if not x in self.par:
			self.par[x] = x
			self.rank[x] = 1
		if not y in self.par:
			self.par[y] = self.par[x]
			return
		par_x = self.find_par(x)
		par_y = self.find_par(y)
		if self.rank[par_x] > self.rank[par_y]:
			self.par[par_y] = par_x
			self.rank[par_y] += self.rank[par_y]
		else:
			self.par[par_x] = par_y
			self.rank[par_x] += self.rank[par_y]

	def find_par(self, x):
		if x == self.par[x]:
			return x
		self.par[x] = self.find_par(self.par[x])
		return self.par[x]

	def is_same_set(self, x, y):
		return self.find_par(x) == self.find_par(y)

def get_caminhos(no):
	caminhos = [[0, -1], [0, 1], [-1, 0], [1, 0]]
	(y, x) = no
	for i in range(4):
		caminhos[i][0] += y
		caminhos[i][1] += x
	caminhos.append(no)
	return caminhos

def overflow(no):
	(y, x) = no
	return True if x < 0 or y < 0 or x >= n or (y >= n) else False
n = int(input())
sheis = tuple((int(v) - 1 for v in input().split()))
shego = tuple((int(v) - 1 for v in input().split()))
planet = {}
for i in range(n):
	line = input()
	for j in range(n):
		if i == 0 and j == 0:
			uf = UnionFind({(i, j): (i, j)})
		elif int(line[j]) == 0:
			filhos = get_caminhos((i, j))
			for f in filhos:
				f = tuple(f)
				if f == (i, j) or (f in planet and planet[f] == 0):
					if f in uf.par:
						uf.union(f, (i, j))
					else:
						uf.union(f, f)
		planet[i, j] = int(line[j])
par_sheis = uf.find_par(sheis)
par_shego = uf.find_par(shego)
if par_sheis == par_shego:
	print(0)
else:
	comp1 = []
	comp2 = []
	for p in uf.par.keys():
		par = uf.find_par(p)
		if par == par_sheis:
			comp1.append(p)
		elif par == par_shego:
			comp2.append(p)
	menor = float('inf')
	for (y1, x1) in comp1:
		for (y2, x2) in comp2:
			custo = (x1 - x2) ** 2 + (y1 - y2) ** 2
			if custo < menor:
				menor = custo
	print(menor)


ans = []
import sys
sys.setrecursionlimit(10 ** 6)

def DFS(adj, v):
	parent = {}

	def DFS_use(v, adj, s):
		sa.add(s)
		for i in adj[s]:
			if i not in parent:
				parent[i] = s
				DFS_use(v, adj, i)
	for s in v:
		if s not in parent:
			sa = {s}
			parent[s] = None
			DFS_use(v, adj, s)
			ans.append(sa)
n = int(input())
(x1, y1) = map(int, input().split())
(x2, y2) = map(int, input().split())
a = [input() for i in range(n)]
adj = {(i, j): [] for i in range(n) for j in range(n)}
for i in range(n):
	for j in range(n):
		if a[i][j] == '1':
			continue
		if i + 1 < n and a[i + 1][j] == '0':
			adj[i, j].append((i + 1, j))
		if j + 1 < n and a[i][j + 1] == '0':
			adj[i, j].append((i, j + 1))
		if i - 1 >= 0 and a[i - 1][j] == '0':
			adj[i, j].append((i - 1, j))
		if j - 1 >= 0 and a[i][j - 1] == '0':
			adj[i, j].append((i, j - 1))
v = [(i, j) for i in range(n) for j in range(n)]
DFS(adj, v)
a1 = set()
a2 = set()
x1 -= 1
x2 -= 1
y1 -= 1
y2 -= 1
for i in ans:
	if (x1, y1) in i:
		a1 = i
		break
if (x2, y2) in a1:
	print(0)
	exit()
for j in ans:
	if (x2, y2) in j:
		a2 = j
		break
sol = 99999

def f(i, j, m, n):
	return (i - m) ** 2 + (j - n) ** 2
for i in a1:
	for j in a2:
		sol = min(sol, f(*i, *j))
print(sol)


from collections import deque
n = int(input())
(y1, x1) = list(map(int, input().split(' ')))
(y2, x2) = list(map(int, input().split(' ')))
y1 -= 1
x1 -= 1
y2 -= 1
x2 -= 1
dat = [input() for _ in range(n)]
bfs1 = [-1] * ((n + 1) * (n + 1))
bfs2 = [-1] * ((n + 1) * (n + 1))

def bfs(res, ys, xs):
	nonlocal dat, n
	d = deque()
	d.append([ys, xs, 0])
	while len(d) != 0:
		(y, x, pr) = d.popleft()
		if y == -1 or x == -1 or y >= n or (x >= n):
			continue
		if dat[y][x] == '1':
			continue
		id = y * n + x
		if res[id] != -1 and res[id] <= pr:
			continue
		res[id] = pr
		pr += 1
		d.append([y + 0, x - 1, pr])
		d.append([y + 0, x + 1, pr])
		d.append([y - 1, x + 0, pr])
		d.append([y + 1, x + 0, pr])
bfs(bfs1, y1, x1)
bfs(bfs2, y2, x2)
if bfs1[y2 * n + x2] != -1:
	print(0)
	return
best = 1000000000000

def pow2(x):
	return x * x
for ys in range(n):
	for xs in range(n):
		ids = ys * n + xs
		if bfs1[ids] == -1:
			continue
		for ye in range(n):
			for xe in range(n):
				ide = ye * n + xe
				if bfs2[ide] == -1:
					continue
				price = pow2(xs - xe) + pow2(ys - ye)
				best = min(best, price)
print(best)


def compute(n, s, d, iswater):
	clt = [[0] * n for _ in range(n)]

	def inrange(y, x):
		return y >= 0 and x >= 0 and (y < n) and (x < n)

	def ff(y, x, color):
		dy = (0, 1, 0, -1)
		dx = (1, 0, -1, 0)
		clt[y][x] = color
		from collections import deque
		q = deque([(y, x)])
		while len(q) > 0:
			(y, x) = q.popleft()
			for (yy, xx) in zip(dy, dx):
				ny = y + yy
				nx = x + xx
				if inrange(ny, nx) and clt[ny][nx] != color and (iswater[y][x] == iswater[ny][nx]):
					clt[ny][nx] = color
					q.append((ny, nx))
	ff(s[0], s[1], 1)
	if clt[d[0]][d[1]] == clt[s[0]][s[1]]:
		return 0
	else:
		ff(d[0], d[1], 2)
	ret = n ** 4
	src = [(sy, sx) for sy in range(n) for sx in range(n) if clt[sy][sx] == 1]
	dst = [(dy, dx) for dy in range(n) for dx in range(n) if clt[dy][dx] == 2]
	for a in src:
		for b in dst:
			c = a[0] - b[0]
			d = a[1] - b[1]
			ret = min(ret, c * c + d * d)
	return ret
from sys import stdin
[n] = list(map(int, stdin.readline().split()))
src = tuple(map(int, stdin.readline().split()))
dst = tuple(map(int, stdin.readline().split()))
iswater = []
for _ in range(n):
	iswater.append(list(map(lambda c: c == '1', stdin.readline().split()[0])))
print(compute(n, (src[0] - 1, src[1] - 1), (dst[0] - 1, dst[1] - 1), iswater))


import sys
sys.setrecursionlimit(100000000)

def faculty(r, c):
	temp.append([r, c])
	if [r, c] not in done:
		done.append([r, c])
		up = r + 1
		down = r - 1
		left = c - 1
		right = c + 1
		if up < n:
			if [up, c] not in done:
				if a[up][c] == 0:
					faculty(up, c)
				else:
					done.append([up, c])
		if down > -1:
			if [down, c] not in done:
				if a[down][c] == 0:
					faculty(down, c)
				else:
					done.append([down, c])
		if left > -1:
			if [r, left] not in done:
				if a[r][left] == 0:
					faculty(r, left)
				else:
					done.append([r, left])
		if right < n:
			if [r, right] not in done:
				if a[r][right] == 0:
					faculty(r, right)
				else:
					done.append([r, right])
n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
a = []
group = []
for _ in range(n):
	ar = [int(x) for x in list(input())]
	a.append(ar)
done = []
temp = []
faculty(r1, c1)
group.append(temp)
if [r2, c2] not in temp:
	temp = []
	faculty(r2, c2)
	group.append(temp)
l = len(group)
g = [[0 for x in range(l)] for x in range(l)]
if l > 1:
	for i in range(l - 1):
		for j in range(i + 1, l):
			cost = []
			for (rl, cl) in group[i]:
				for (rr, cr) in group[j]:
					value = (rl - rr) ** 2 + (cl - cr) ** 2
					cost.append(value)
	print(min(cost))
else:
	print(0)


n = int(input())
st = list(map(int, input().split(' ')))
en = list(map(int, input().split(' ')))
matrix = []
for i in range(n):
	lis = list(input())
	matrix.append([int(a) for a in lis])
stack = [st]
start_banks = []
rep = {}
while stack:
	cur = stack.pop()
	rep[tuple(cur)] = 1
	if cur == en:
		print(0)
		exit()
	if matrix[cur[0] - 1][cur[1] - 1] == 0:
		if cur[0] - 1 > 0:
			if [cur[0] - 1, cur[1]] == en:
				print(0)
				exit()
			if matrix[cur[0] - 1 - 1][cur[1] - 1] == 1:
				start_banks.append([cur[0], cur[1]])
			elif tuple([cur[0] - 1, cur[1]]) not in rep:
				stack.append([cur[0] - 1, cur[1]])
		if cur[0] + 1 <= n:
			if [cur[0] + 1, cur[1]] == en:
				print(0)
				exit()
			if matrix[cur[0] + 1 - 1][cur[1] - 1] == 1:
				start_banks.append([cur[0], cur[1]])
			elif tuple([cur[0] + 1, cur[1]]) not in rep:
				stack.append([cur[0] + 1, cur[1]])
		if cur[1] - 1 > 0:
			if [cur[0], cur[1] - 1] == en:
				print(0)
				exit()
			if matrix[cur[0] - 1][cur[1] - 1 - 1] == 1:
				start_banks.append([cur[0], cur[1]])
			elif tuple([cur[0], cur[1] - 1]) not in rep:
				stack.append([cur[0], cur[1] - 1])
		if cur[1] + 1 <= n:
			if [cur[0], cur[1] + 1] == en:
				print(0)
				exit()
			if matrix[cur[0] - 1][cur[1] + 1 - 1] == 1:
				start_banks.append([cur[0], cur[1]])
			elif tuple([cur[0], cur[1] + 1]) not in rep:
				stack.append([cur[0], cur[1] + 1])
stack = [en]
end_banks = []
rep = {}
while stack:
	cur = stack.pop()
	rep[tuple(cur)] = 1
	if matrix[cur[0] - 1][cur[1] - 1] == 0:
		if cur[0] - 1 > 0:
			if matrix[cur[0] - 1 - 1][cur[1] - 1] == 1:
				end_banks.append([cur[0], cur[1]])
			elif tuple([cur[0] - 1, cur[1]]) not in rep:
				stack.append([cur[0] - 1, cur[1]])
		if cur[0] + 1 <= n:
			if matrix[cur[0] + 1 - 1][cur[1] - 1] == 1:
				end_banks.append([cur[0], cur[1]])
			elif tuple([cur[0] + 1, cur[1]]) not in rep:
				stack.append([cur[0] + 1, cur[1]])
		if cur[1] - 1 > 0:
			if matrix[cur[0] - 1][cur[1] - 1 - 1] == 1:
				end_banks.append([cur[0], cur[1]])
			elif tuple([cur[0], cur[1] - 1]) not in rep:
				stack.append([cur[0], cur[1] - 1])
		if cur[1] + 1 <= n:
			if matrix[cur[0] - 1][cur[1] + 1 - 1] == 1:
				end_banks.append([cur[0], cur[1]])
			elif tuple([cur[0], cur[1] + 1]) not in rep:
				stack.append([cur[0], cur[1] + 1])
res = []
for st_bank in start_banks:
	for en_bank in end_banks:
		res.append(pow(st_bank[0] - en_bank[0], 2) + pow(st_bank[1] - en_bank[1], 2))
print(min(res))


n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
l = []
for _ in range(n):
	l.append(list(input()))
aux = [[] for _ in range(2)]
s = 0
next = [[0, -1], [0, 1], [-1, 0], [1, 0]]

def bfs(x, y):
	q = [[x, y]]
	while len(q):
		(i, j) = q.pop()
		l[i][j] = '1'
		aux[s].append([i, j])
		for (a, b) in next:
			ni = i + a
			nj = j + b
			if ni >= 0 and nj >= 0 and (ni < n) and (nj < n):
				if l[ni][nj] == '0':
					q.append([ni, nj])
bfs(r1, c1)
if l[r2][c2] == 1:
	print(0)
else:
	s += 1
	bfs(r2, c2)
	res = 5000
	for (x1, y1) in aux[0]:
		for (x2, y2) in aux[1]:
			res = min(res, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(res)


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = [['1'] * (n + 2)]
for _ in range(n):
	s = input()
	d = ['1']
	for i in s:
		d.append(i)
	d.append('1')
	a.append(d)
a.append(['1'] * (n + 2))
s = []
f = []
q = [[r1, c1]]
while q:
	(x, y) = q.pop()
	a[x][y] = '1'
	s.append([x, y])
	if a[x - 1][y] == '0':
		q.append([x - 1, y])
	if a[x][y - 1] == '0':
		q.append([x, y - 1])
	if a[x + 1][y] == '0':
		q.append([x + 1, y])
	if a[x][y + 1] == '0':
		q.append([x, y + 1])
if [r2, c2] in s:
	print(0)
else:
	q = [[r2, c2]]
	while q:
		(x, y) = q.pop()
		a[x][y] = '1'
		f.append([x, y])
		if a[x - 1][y] == '0':
			q.append([x - 1, y])
		if a[x][y - 1] == '0':
			q.append([x, y - 1])
		if a[x + 1][y] == '0':
			q.append([x + 1, y])
		if a[x][y + 1] == '0':
			q.append([x, y + 1])
	res = 10 ** 10
	for i in s:
		for j in f:
			res = min(res, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
	print(res)


import sys
sys.setrecursionlimit(10 ** 8)
input = sys.stdin.readline
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = []

def visit(a, vis, i, j, c, n):
	if i < 0 or j < 0 or i == n or (j == n):
		return
	else:
		if a[i][j] == 1 or vis[i][j] != -18:
			return
		vis[i][j] = c
		visit(a, vis, i - 1, j, c, n)
		visit(a, vis, i + 1, j, c, n)
		visit(a, vis, i, j - 1, c, n)
		visit(a, vis, i, j + 1, c, n)
for i in range(n):
	p = list(input().rstrip())
	for ii in range(n):
		p[ii] = int(p[ii])
	a.append(p)
c = 1
vis = [[-18 for i in range(n)] for j in range(n)]
for i in range(n):
	for j in range(n):
		if a[i][j] == 1:
			vis[i][j] = -1
		elif vis[i][j] != -18:
			continue
		else:
			visit(a, vis, i, j, c, n)
			c += 1
dis = [[] for i in range(c)]
for i in range(n):
	for j in range(n):
		if a[i][j] == 0:
			dis[vis[i][j]].append([i + 1, j + 1])
d = {}
for i in range(1, c):
	for j in range(i + 1, c):
		d[str(i) + '*' + str(j)] = mini = 99999999999
		li = len(dis[i])
		lj = len(dis[j])
		for k in range(li):
			for p in range(lj):
				mini = min(mini, (dis[i][k][0] - dis[j][p][0]) ** 2 + (dis[i][k][1] - dis[j][p][1]) ** 2)
		d[str(i) + '*' + str(j)] = mini
		d[str(j) + '*' + str(i)] = mini
print(d[str(vis[r1 - 1][c1 - 1]) + '*' + str(vis[r2 - 1][c2 - 1])] if str(vis[r1 - 1][c1 - 1]) + '*' + str(vis[r2 - 1][c2 - 1]) in d else 0)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = []
for i in range(n):
	a.append(input())
a1 = []
a2 = []

def dfs1(i, j):
	if (i, j) in a1:
		return
	if max(i, j) >= n or min(i, j) < 0:
		return
	if a[i][j] == '1':
		return
	a1.append((i, j))
	dfs1(i + 1, j)
	dfs1(i - 1, j)
	dfs1(i, j + 1)
	dfs1(i, j - 1)
	return

def dfs2(i, j):
	if (i, j) in a2:
		return
	if max(i, j) >= n or min(i, j) < 0:
		return
	if a[i][j] == '1':
		return
	a2.append((i, j))
	dfs2(i + 1, j)
	dfs2(i - 1, j)
	dfs2(i, j + 1)
	dfs2(i, j - 1)
	return
dfs1(r1 - 1, c1 - 1)
if (r2 - 1, c2 - 1) in a1:
	print(0)
	exit()
dfs2(r2 - 1, c2 - 1)
ans = 1000000000.0
for i in a1:
	for j in a2:
		x = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
		ans = min(ans, x)
print(ans)


def dfs(r1, r2):
	global cnt
	cnt[r1][r2] = 1
	if r1 + 1 < n and a[r1 + 1][r2] == 0 and (cnt[r1 + 1][r2] == 0):
		dfs(r1 + 1, r2)
	if r1 - 1 > -1 and a[r1 - 1][r2] == 0 and (cnt[r1 - 1][r2] == 0):
		dfs(r1 - 1, r2)
	if r2 + 1 < n and a[r1][r2 + 1] == 0 and (cnt[r1][r2 + 1] == 0):
		dfs(r1, r2 + 1)
	if r2 - 1 > -1 and a[r1][r2 - 1] == 0 and (cnt[r1][r2 - 1] == 0):
		dfs(r1, r2 - 1)
(n,) = [int(i) for i in input().split()]
(r1, c1) = [int(i) - 1 for i in input().split()]
(r2, c2) = [int(i) - 1 for i in input().split()]
a = []
for i in range(n):
	a.append([int(i) for i in input()])
cnt = [[0] * n for i in range(n)]
dfs(r1, c1)
if cnt[r1][c1] == 1 and cnt[r2][c2] == 1:
	print(0)
	exit(0)
beg = []
for i in range(n):
	for j in range(n):
		if cnt[i][j] == 1:
			beg.append([i, j])
cnt = [[0] * n for i in range(n)]
dfs(r2, c2)
end = []
for i in range(n):
	for j in range(n):
		if cnt[i][j] == 1:
			end.append([i, j])
ans = 10 ** 9
for i in beg:
	for j in end:
		ans = min(ans, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(ans)


from collections import deque
n = int(input())
(r1, c1) = (int(t) - 1 for t in input().split(' '))
(r2, c2) = (int(t) - 1 for t in input().split(' '))
mx = [input() for _ in range(n)]
visited = [[0] * n for _ in range(n)]

def bfs(start, mark):
	q = deque()
	q.append(start)
	while len(q):
		(r, c) = q.popleft()
		if visited[r][c]:
			continue
		visited[r][c] = mark
		dirs = [(t[0] + r, t[1] + c) for t in [(0, 1), (1, 0), (-1, 0), (0, -1)] if t[0] + r < n and t[0] + r >= 0 and (t[1] + c < n) and (t[1] + c >= 0)]
		dirs = [d for d in dirs if not visited[d[0]][d[1]] and mx[d[0]][d[1]] == '0']
		for d in dirs:
			q.append(d)
bfs((r1, c1), 1)
if visited[r2][c2] == 1:
	print(0)
else:
	bfs((r2, c2), 2)
	firsts = [(i, j) for i in range(n) for j in range(n) if visited[i][j] == 1]
	seconds = [(i, j) for i in range(n) for j in range(n) if visited[i][j] == 2]
	result = min(((f[0] - s[0]) ** 2 + (f[1] - s[1]) ** 2 for f in firsts for s in seconds))
	print(result)


n = int(input())
start = [int(number) - 1 for number in input().split()]
end = [int(number) - 1 for number in input().split()]
mapp = []
for ii in range(n):
	mapp.append(input())

def CheckNode(nodee):
	if 0 <= nodee[0] < n and 0 <= nodee[1] < n:
		if mapp[nodee[0]][nodee[1]] == '0':
			return '0'
		else:
			return '1'
	else:
		return '1'

def CheckConnected(node):
	pass

def ConnectedList(node):
	cnodes = [node]
	vnodes = []
	while cnodes != []:
		for item in cnodes:
			if CheckNode([item[0] - 1, item[1]]) == '0':
				if [item[0] - 1, item[1]] not in vnodes and [item[0] - 1, item[1]] not in cnodes:
					cnodes.append([item[0] - 1, item[1]])
			if CheckNode([item[0], item[1] + 1]) == '0':
				if [item[0], item[1] + 1] not in vnodes and [item[0], item[1] + 1] not in cnodes:
					cnodes.append([item[0], item[1] + 1])
			if CheckNode([item[0] + 1, item[1]]) == '0':
				if [item[0] + 1, item[1]] not in vnodes and [item[0] + 1, item[1]] not in cnodes:
					cnodes.append([item[0] + 1, item[1]])
			if CheckNode([item[0], item[1] - 1]) == '0':
				if [item[0], item[1] - 1] not in vnodes and [item[0], item[1] - 1] not in cnodes:
					cnodes.append([item[0], item[1] - 1])
			cnodes.remove(item)
			vnodes.append(item)
	return vnodes

def cost(aa, bb):
	ac = aa[0] - bb[0]
	ac *= ac
	ad = aa[1] - bb[1]
	ad *= ad
	return ac + ad
startConnected = ConnectedList(start)
costv = 0
if end in startConnected:
	print(0)
else:
	endConnected = ConnectedList(end)
	for node in startConnected:
		for nodee in endConnected:
			costm = cost(node, nodee)
			if costv == 0:
				costv = costm
			elif costm < costv:
				costv = costm
	print(costv)


def funciona(x, y):
	return 0 <= x < n and 0 <= y < n

def bfs(vis, u, v):
	fila = [(u, v)]
	vis.add((u, v))
	while fila:
		(u, v) = fila[0]
		fila = fila[1:]
		for m in movimentosPossiveis:
			(x, y) = (u + m[0], v + m[1])
			if (x, y) not in vis and funciona(x, y) and (lista[x][y] == '0'):
				vis.add((x, y))
				fila.append((x, y))
movimentosPossiveis = [[1, 0], [-1, 0], [0, 1], [0, -1]]
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
lista = []
for i in range(n):
	lista.append(input())
comeco = set()
fim = set()
bfs(comeco, r1, c1)
bfs(fim, r2, c2)
if (r2, c2) in comeco:
	print(0)
else:
	res = int(1000000000.0)
	for a in comeco:
		for b in fim:
			res = min(res, (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
	print(res)


import sys
sys.setrecursionlimit(21 * 10 ** 8)

def do1(x, y):
	used1[x][y] = True
	cart1[x - 1][y - 1] = 1
	if not used1[x - 1][y] and maps[x - 1][y] == 0:
		do1(x - 1, y)
	if not used1[x + 1][y] and maps[x + 1][y] == 0:
		do1(x + 1, y)
	if not used1[x][y - 1] and maps[x][y - 1] == 0:
		do1(x, y - 1)
	if not used1[x][y + 1] and maps[x][y + 1] == 0:
		do1(x, y + 1)

def do2(x, y):
	used2[x][y] = True
	cart2[x - 1][y - 1] = 2
	if not used2[x - 1][y] and maps[x - 1][y] == 0:
		do2(x - 1, y)
	if not used2[x + 1][y] and maps[x + 1][y] == 0:
		do2(x + 1, y)
	if not used2[x][y - 1] and maps[x][y - 1] == 0:
		do2(x, y - 1)
	if not used2[x][y + 1] and maps[x][y + 1] == 0:
		do2(x, y + 1)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
maps = []
cart1 = []
cart2 = []
used1 = []
used2 = []
maps.append([])
used1.append([])
used2.append([])
for i in range(n + 2):
	maps[0].append(1)
	used1[0].append(False)
	used2[0].append(False)
for i in range(n):
	s = list(input())
	maps.append([])
	cart1.append([])
	cart2.append([])
	used1.append([False])
	used2.append([False])
	maps[i + 1].append(1)
	for j in range(n):
		maps[i + 1].append(int(s[j]))
		cart1[i].append(0)
		cart2[i].append(0)
		used1[i + 1].append(False)
		used2[i + 1].append(False)
	maps[i + 1].append(1)
	used1[i + 1].append(False)
	used2[i + 1].append(False)
maps.append([])
used1.append([])
used2.append([])
for i in range(n + 2):
	maps[n + 1].append(1)
	used1[n + 1].append(False)
	used2[n + 1].append(False)
do1(r1, c1)
do2(r2, c2)
minans = 10 ** 18
flag = False
for i in range(n):
	for j in range(n):
		for k in range(n):
			for l in range(n):
				if cart1[i][j] == 1 and cart2[k][l] == 2 and (i == k) and (j == l):
					flag = True
				if cart1[i][j] == 1 and cart2[k][l] == 2:
					minans = min(minans, (i - k) ** 2 + (j - l) ** 2)
if flag:
	print(0)
else:
	print(minans)


def bfs(r, c, matrix):
	n = len(matrix)
	visited = dict()
	queue = []
	queue.append((r, c))
	visited[r, c] = True
	while len(queue) != 0:
		(x, y) = queue.pop(0)
		if x + 1 < n and (not visited.get((x + 1, y), False)) and (matrix[x + 1][y] == '0'):
			queue.append((x + 1, y))
			visited[x + 1, y] = True
		if x - 1 >= 0 and (not visited.get((x - 1, y), False)) and (matrix[x - 1][y] == '0'):
			queue.append((x - 1, y))
			visited[x - 1, y] = True
		if y + 1 < n and (not visited.get((x, y + 1), False)) and (matrix[x][y + 1] == '0'):
			queue.append((x, y + 1))
			visited[x, y + 1] = True
		if y - 1 >= 0 and (not visited.get((x, y - 1), False)) and (matrix[x][y - 1] == '0'):
			queue.append((x, y - 1))
			visited[x, y - 1] = True
	return list(visited.keys())
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
matrix = [input() for _ in range(n)]
poss1 = bfs(r1 - 1, c1 - 1, matrix)
poss2 = bfs(r2 - 1, c2 - 1, matrix)
best = float('inf')
for (x1, y1) in poss1:
	for (x2, y2) in poss2:
		d = (x1 - x2) ** 2 + (y1 - y2) ** 2
		if d < best:
			best = d
		if best == 0:
			print(0)
			exit(0)
print(best)


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
l = []
for i in range(n):
	l.append(list(map(int, input())))
q = [(r1 - 1, c1 - 1)]
v = {(i, j): False for i in range(n) for j in range(n)}
a = []
while len(q) != 0:
	(r, c) = q.pop()
	if v[r, c]:
		continue
	a.append((r, c))
	v[r, c] = True
	if c < n - 1 and l[r][c + 1] == 0:
		q.append((r, c + 1))
	if c > 0 and l[r][c - 1] == 0:
		q.append((r, c - 1))
	if r < n - 1 and l[r + 1][c] == 0:
		q.append((r + 1, c))
	if r > 0 and l[r - 1][c] == 0:
		q.append((r - 1, c))
q = [(r2 - 1, c2 - 1)]
v = {(i, j): False for i in range(n) for j in range(n)}
b = []
while len(q) != 0:
	(r, c) = q.pop()
	if v[r, c]:
		continue
	b.append((r, c))
	v[r, c] = True
	if c < n - 1 and l[r][c + 1] == 0:
		q.append((r, c + 1))
	if c > 0 and l[r][c - 1] == 0:
		q.append((r, c - 1))
	if r < n - 1 and l[r + 1][c] == 0:
		q.append((r + 1, c))
	if r > 0 and l[r - 1][c] == 0:
		q.append((r - 1, c))
c = float('inf')
for (x1, y1) in a:
	for (x2, y2) in b:
		c = min(c, (x1 - x2) ** 2 + (y1 - y2) ** 2)
print(c)


from queue import PriorityQueue

def neighbours(n, actual):
	position = []
	positions = [(-1, 0), (0, 1), (1, 0), (0, -1)]
	for (x, y) in positions:
		new_x = actual // n + x
		new_y = actual % n + y
		if new_x >= 0 and new_x < n and (new_y >= 0) and (new_y < n):
			position.append((new_x, new_y))
	return position

def distance(a, b, n):
	(ax, ay) = (a // n, a % n)
	(bx, by) = (b // n, b % n)
	return int((ax - bx) ** 2 + (ay - by) ** 2)

def DFS_group(array, n, group_connected_components, group_number, actual):
	group_connected_components[actual] = group_number
	for (new_x, new_y) in neighbours(n, actual):
		if new_x >= 0 and new_x < n and (new_y >= 0) and (new_y < n) and (int(array[new_x][new_y]) == 0) and (group_connected_components[new_x * n + new_y % n] is None):
			DFS_group(array, n, group_connected_components, group_number, new_x * n + new_y % n)

def connect():
	n = int(input())
	begining = [int(el) for el in input().split()]
	b = (begining[0] - 1) * n + begining[1] - 1
	end = [int(el) for el in input().split()]
	e = (end[0] - 1) * n + end[1] - 1
	array = [input() for _ in range(n)]
	counter = 0
	for string in array:
		for letter in string:
			if letter == '1':
				counter += 1
	if counter <= 2:
		return 0
	groups = [None] * n ** 2
	group_number = -1
	for i in range(n ** 2):
		if groups[i] == None and int(array[i // n][i % n]) != 1:
			group_number += 1
			DFS_group(array, n, groups, group_number, i)
	if groups[e] == groups[b]:
		return 0
	A = []
	B = []
	for i in range(n ** 2):
		if groups[i] == groups[b]:
			A.append(i)
		elif groups[i] == groups[e]:
			B.append(i)
	cheapest_tunel = float('inf')
	for i in range(len(A)):
		for j in range(len(B)):
			cheapest_tunel = min(cheapest_tunel, distance(A[i], B[j], n))
	return cheapest_tunel
print(connect())


import sys
sys.setrecursionlimit(5000)

def mod_acc(g, h, modby):
	global m, n
	if 0 <= g < n and 0 <= h < n and (m[g][h] == 1):
		m[g][h] += modby
		return 1 + mod_acc(g - 1, h, modby) + mod_acc(g + 1, h, modby) + mod_acc(g, h - 1, modby) + mod_acc(g, h + 1, modby)
	else:
		return 0
n = int(input())
(r1, c1) = [int(tmp) for tmp in input().split()]
(r2, c2) = [int(tmp) for tmp in input().split()]
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
m = []
for i in range(n):
	m.append([1 - int(tmp) for tmp in input().strip()])
s1 = mod_acc(r1, c1, 100)
s2 = mod_acc(r2, c2, 200)
if s2 == 0:
	print(0)
	exit(0)
lsi = []
lti = []
for r in range(n):
	for c in range(n):
		if m[r][c] == 101:
			lsi.append((r, c))
		elif m[r][c] == 201:
			lti.append((r, c))
mic = n ** 2 * 2
for s in lsi:
	for t in lti:
		mic = min(mic, (s[0] - t[0]) ** 2 + (s[1] - t[1]) ** 2)
		if mic == 2:
			break
	if mic == 2:
		break
print(mic)


from sys import stdin
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())

def mac(x, y):
	cr = [(x, y)]
	v = [[1] * (n + 2) for i in range(n + 2)]
	stack = [(x, y)]
	v[x][y] = 0
	while stack:
		(r, c) = stack.pop()
		if a[r + 1][c] == '0' and v[r + 1][c]:
			stack.append((r + 1, c))
			cr.append((r + 1, c))
			v[r + 1][c] = 0
		if a[r - 1][c] == '0' and v[r - 1][c]:
			stack.append((r - 1, c))
			cr.append((r - 1, c))
			v[r - 1][c] = 0
		if a[r][c + 1] == '0' and v[r][c + 1]:
			stack.append((r, c + 1))
			cr.append((r, c + 1))
			v[r][c + 1] = 0
		if a[r][c - 1] == '0' and v[r][c - 1]:
			stack.append((r, c - 1))
			cr.append((r, c - 1))
			v[r][c - 1] = 0
	return cr
n = I()
(r1, c1) = R()
(r2, c2) = R()
a = ['1' * (n + 2)]
for i in range(n):
	a.append('1' + input().rstrip('\n') + '1')
a.append('1' * (n + 2))
p1 = mac(r1, c1)
p2 = mac(r2, c2)
ans = []
for i in p1:
	for j in p2:
		ans += ((i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2,)
print(min(ans))


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
(r1, c1, r2, c2) = (r1 - 1, c1 - 1, r2 - 1, c2 - 1)
g = []
for i in range(n):
	g.append(list(map(int, list(input()))))
from_r1 = set()
from_r2 = set()
x = [0, 1, 0, -1]
y = [1, 0, -1, 0]
visited = [[False for i in range(n)] for j in range(n)]
stack = [(r1, c1)]
while stack:
	v = stack.pop()
	if v[0] == r2 and v[1] == c2:
		print(0)
		exit()
	visited[v[0]][v[1]] = True
	for i in range(4):
		if v[0] + x[i] < n and v[1] + y[i] < n and (v[0] + x[i] >= 0) and (v[1] + y[i] >= 0) and (not visited[v[0] + x[i]][v[1] + y[i]]):
			if g[v[0] + x[i]][v[1] + y[i]] == 0:
				stack.append((v[0] + x[i], v[1] + y[i]))
			else:
				from_r1.add((v[0], v[1]))
visited = [[False for i in range(n)] for j in range(n)]
stack = [(r2, c2)]
while stack:
	v = stack.pop()
	visited[v[0]][v[1]] = True
	for i in range(4):
		if v[0] + x[i] < n and v[1] + y[i] < n and (v[0] + x[i] >= 0) and (v[1] + y[i] >= 0) and (not visited[v[0] + x[i]][v[1] + y[i]]):
			if g[v[0] + x[i]][v[1] + y[i]] == 0:
				stack.append((v[0] + x[i], v[1] + y[i]))
			else:
				from_r2.add((v[0], v[1]))
min_value = 100000000
for i in from_r1:
	for j in from_r2:
		min_value = min((i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2, min_value)
print(min_value)


from collections import deque
from math import inf

def bfs(grafo, n, no, ans, vis):
	ver = []
	q = deque()
	q.append(no)
	vis[no[0]][no[1]] = True
	ver.append(no)
	while q:
		top = q.popleft()
		aux = []
		if top[0] + 1 < n and grafo[top[0] + 1][top[1]] == '0':
			aux.append((top[0] + 1, top[1]))
		if top[0] - 1 >= 0 and grafo[top[0] - 1][top[1]] == '0':
			aux.append((top[0] - 1, top[1]))
		if top[1] + 1 < n and grafo[top[0]][top[1] + 1] == '0':
			aux.append((top[0], top[1] + 1))
		if top[1] - 1 >= 0 and grafo[top[0]][top[1] - 1] == '0':
			aux.append((top[0], top[1] - 1))
		for vizinho in aux:
			if not vis[vizinho[0]][vizinho[1]]:
				vis[vizinho[0]][vizinho[1]] = True
				ver.append(vizinho)
				q.append(vizinho)
				if vizinho == ans:
					return None
	return ver
n = int(input())
inicio = tuple(map(lambda v: int(v) - 1, input().split()))
chegada = tuple(map(lambda v: int(v) - 1, input().split()))
grafo = [[] for _ in range(n)]
vis = [[] for __ in range(n)]
for x in range(n):
	aux = input()
	for y in range(n):
		grafo[x].append(aux[y])
		vis[x].append(False)
ver1 = bfs(grafo, n, inicio, chegada, vis)
if ver1:
	minimo = inf
	ver2 = bfs(grafo, n, chegada, None, vis)
	for i in ver1:
		for j in ver2:
			minimo = min(minimo, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
	print(minimo)
else:
	print(0)


from sys import setrecursionlimit
setrecursionlimit(10 ** 9)
from sys import stdin
input = stdin.readline

def dfs(r, c, mark, A):
	if r < 0 or r >= n or c < 0 or (c >= n):
		return
	if a[r][c] == 1:
		return
	if a[r][c] == mark:
		return
	a[r][c] = mark
	A.append((r, c))
	for (x, y) in ((0, 1), (0, -1), (1, 0), (-1, 0)):
		dfs(r + x, c + y, mark, A)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = [[int(s) for s in input()[:n]] for _ in range(n)]
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
A = []
dfs(r1, c1, 2, A)
if a[r2][c2] == 2:
	print(0)
	exit()
B = []
ans = 2 * n ** 2
dfs(r2, c2, 3, B)
for (a, b) in A:
	for (c, d) in B:
		ans = min(ans, (c - a) ** 2 + (d - b) ** 2)
print(ans)


from sys import stdin

def check(g, x, y):
	return len(g) > x >= 0 and len(g[0]) > y >= 0 and (g[x][y] is 0)

def find_land(g, pos):
	q = [pos]
	land = set()
	visited = set()
	while q:
		(x, y) = q.pop()
		land.add((x, y))
		if (x, y) not in visited:
			visited.add((x, y))
			if check(g, x + 1, y):
				q.append((x + 1, y))
			if check(g, x, y + 1):
				q.append((x, y + 1))
			if check(g, x - 1, y):
				q.append((x - 1, y))
			if check(g, x, y - 1):
				q.append((x, y - 1))
	return land
n = int(stdin.readline())
st = [int(x) - 1 for x in stdin.readline().rstrip().split()]
end = [int(x) - 1 for x in stdin.readline().rstrip().split()]
g = []
for i in range(n):
	l = stdin.readline()
	g.append([])
	for v in range(n):
		g[i].append(int(l[v]))
l = find_land(g, (st[0], st[1]))
dest = find_land(g, (end[0], end[1]))
min_d = (n - 1) ** 2 + (n - 1) ** 2
if (end[0], end[1]) in l:
	print(0)
	exit()
for el in l:
	for el2 in dest:
		d = (el[0] - el2[0]) ** 2 + (el[1] - el2[1]) ** 2
		if d < min_d:
			min_d = d
print(min_d)


from sys import exit, setrecursionlimit
setrecursionlimit(10 ** 6)
inn = lambda : input().strip()
mapp = lambda : map(int, inn().split(' '))
N = int(inn())
(startX, startY) = mapp()
startX -= 1
startY -= 1
(endX, endY) = mapp()
endX -= 1
endY -= 1
planet = tuple((inn() for _ in range(N)))
landId = [[-1] * N for _ in range(N)]
counter = 0

def dfs(y, x):
	if landId[y][x] != -1:
		return
	if planet[y][x] == '1':
		return
	landId[y][x] = counter
	if x + 1 < N:
		dfs(y, x + 1)
	if x - 1 >= 0:
		dfs(y, x - 1)
	if y + 1 < N:
		dfs(y + 1, x)
	if y - 1 >= 0:
		dfs(y - 1, x)
for y in range(N):
	for x in range(N):
		if landId[y][x] == -1:
			dfs(y, x)
			counter += 1
from collections import defaultdict
dd = defaultdict(list)
for y in range(N):
	for x in range(N):
		dd[landId[y][x]].append((y, x))
answer = 987654321
if landId[startX][startY] == landId[endX][endY]:
	print(0)
	exit()
for (y1, x1) in dd[landId[startX][startY]]:
	for (y2, x2) in dd[landId[endX][endY]]:
		answer = min(answer, abs(y1 - y2) ** 2 + abs(x1 - x2) ** 2)
print(answer)


n = int(input())
terra = []
vis = []
mora = []
destino = []
(r1, c1) = map(int, input().split())
mora.append([r1, c1])
(r2, c2) = map(int, input().split())
destino.append([r2, c2])
(originalr1, originalc1) = (r1, c1)
(originalr2, originalc2) = (r1, c1)
for i in range(1, n + 1):
	s = input()
	s = list(s)
	for j in range(1, len(s) + 1):
		if s[j - 1] == '0':
			terra.append([i, j])
			vis.append(0)
z = -1
w = -1
for m in range(len(terra)):
	if terra[m] == [r1, c1]:
		z = m
for m in range(len(terra)):
	if terra[m] == [r2, c2]:
		w = m

def dfs_mora(i):
	global r1, c1
	pilha = []
	pilha.append(i)
	while len(pilha) > 0:
		nohatual = pilha.pop()
		if vis[nohatual] != 1:
			vis[nohatual] = 1
			r1 = terra[nohatual][0]
			c1 = terra[nohatual][1]
			for y in range(len(terra)):
				if vis[y] != 1:
					if abs(terra[y][0] - r1) <= 1 and terra[y][1] == c1 or (abs(terra[y][1] - c1) <= 1 and terra[y][0] == r1):
						mora.append(terra[y])
						pilha.append(y)

def dfs_destino(i):
	global r2, c2
	pilha = []
	pilha.append(i)
	while len(pilha) > 0:
		nohatual = pilha.pop()
		if vis[nohatual] != 1:
			vis[nohatual] = 1
			r2 = terra[nohatual][0]
			c2 = terra[nohatual][1]
			for y in range(len(terra)):
				if vis[y] != 1:
					if abs(terra[y][0] - r2) <= 1 and terra[y][1] == c2 or (abs(terra[y][1] - c2) <= 1 and terra[y][0] == r2):
						destino.append(terra[y])
						pilha.append(y)
dfs_mora(z)
dfs_destino(w)
menor = 5002
if [originalr1, originalc1] in destino:
	print(0)
else:
	for m in range(len(mora)):
		for d in range(len(destino)):
			if (mora[m][0] - destino[d][0]) ** 2 + (mora[m][1] - destino[d][1]) ** 2 < menor:
				menor = (mora[m][0] - destino[d][0]) ** 2 + (mora[m][1] - destino[d][1]) ** 2
	print(menor)


def neighbors(p, n):
	output = []
	(x, y) = (p[0], p[1])
	if x > 0:
		output.append([x - 1, y])
	if x < n - 1:
		output.append([x + 1, y])
	if y > 0:
		output.append([x, y - 1])
	if y < n - 1:
		output.append([x, y + 1])
	return output

def component(x, y, grid, n):
	done = []
	used = {}
	for i in range(n):
		for j in range(n):
			used[100 * i + j] = 0
	todo = [[x, y]]
	while len(todo) > 0:
		next = todo.pop(0)
		done.append(next)
		used[100 * next[0] + next[1]] = 1
		for x in neighbors(next, n):
			if grid[x[0]][x[1]] == 0 and used[100 * x[0] + x[1]] == 0:
				todo.append(x)
				used[100 * x[0] + x[1]] = 1
	return done
n = int(input())
(x1, y1) = [int(x) - 1 for x in input().split()]
(x2, y2) = [int(x) - 1 for x in input().split()]
grid = []
for _ in range(n):
	grid.append([int(x) for x in input()])
component1 = component(x1, y1, grid, n)
component2 = component(x2, y2, grid, n)
if [x1, y1] in component2:
	print(0)
else:
	bestdistance = 99999999
	for z1 in component1:
		for z2 in component2:
			dist = (z1[0] - z2[0]) ** 2 + (z1[1] - z2[1]) ** 2
			bestdistance = min(bestdistance, dist)
	print(bestdistance)


from collections import deque
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
grid = []
for i in range(n):
	grid.append(list(input()))
visited1 = set()
quee1 = deque()
quee1.append((r1 - 1, c1 - 1))
visited1.add((r1 - 1, c1 - 1))
while quee1:
	(c, r) = quee1.popleft()
	if r > 0:
		if grid[c][r - 1] == '0' and (c, r - 1) not in visited1:
			quee1.append((c, r - 1))
			visited1.add((c, r - 1))
	if r < n - 1:
		if grid[c][r + 1] == '0' and (c, r + 1) not in visited1:
			quee1.append((c, r + 1))
			visited1.add((c, r + 1))
	if c > 0:
		if grid[c - 1][r] == '0' and (c - 1, r) not in visited1:
			quee1.append((c - 1, r))
			visited1.add((c - 1, r))
	if c < n - 1:
		if grid[c + 1][r] == '0' and (c + 1, r) not in visited1:
			quee1.append((c + 1, r))
			visited1.add((c + 1, r))
visited2 = set()
quee2 = deque()
quee2.append((r2 - 1, c2 - 1))
visited2.add((r2 - 1, c2 - 1))
while quee2:
	(c, r) = quee2.popleft()
	if r > 0:
		if grid[c][r - 1] == '0' and (c, r - 1) not in visited2:
			quee2.append((c, r - 1))
			visited2.add((c, r - 1))
	if r < n - 1:
		if grid[c][r + 1] == '0' and (c, r + 1) not in visited2:
			quee2.append((c, r + 1))
			visited2.add((c, r + 1))
	if c > 0:
		if grid[c - 1][r] == '0' and (c - 1, r) not in visited2:
			quee2.append((c - 1, r))
			visited2.add((c - 1, r))
	if c < n - 1:
		if grid[c + 1][r] == '0' and (c + 1, r) not in visited2:
			quee2.append((c + 1, r))
			visited2.add((c + 1, r))
m = 1000000000
for i in visited1:
	for j in visited2:
		x = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
		if x < m:
			m = x
print(m)


N = int(input())
from collections import deque
(a1, a2) = list(map(int, input().split()))
(b1, b2) = list(map(int, input().split()))
(a1, a2, b1, b2) = (a1 - 1, a2 - 1, b1 - 1, b2 - 1)
map = []
for i in range(N):
	p = list(input())
	map.append(p)
comp1 = [(a1, a2)]
comp2 = [(b1, b2)]

def neib(x, y):
	ns = []
	if x + 1 < N:
		ns.append((x + 1, y))
	if x != 0:
		ns.append((x - 1, y))
	if y + 1 < N:
		ns.append((x, y + 1))
	if y != 0:
		ns.append((x, y - 1))
	return ns
c1 = deque(comp1)
c1seen = []
c1e = []
while c1:
	gn = 0
	g = c1.pop()
	nb = neib(g[0], g[1])
	for n in nb:
		if n not in c1seen:
			if map[n[0]][n[1]] != '1':
				c1.append(n)
				gn += 1
	c1seen.append(g)
	if gn < 4:
		c1e.append(g)
c2 = deque(comp2)
c2seen = []
c2e = []
while c2:
	g = c2.pop()
	nb = neib(g[0], g[1])
	gn = 0
	for n in nb:
		if n not in c2seen:
			if map[n[0]][n[1]] != '1':
				gn += 1
				c2.append(n)
	c2seen.append(g)
	if gn < 4:
		c2e.append(g)
distt = 10 ** 5

def dist(a, b):
	return (a[0] - b[0]) ** 2 + (b[1] - a[1]) ** 2
for a in c2e:
	for b in c1e:
		distt = min(distt, dist(a, b))
print(distt)


from collections import deque
n = int(input())
(r1, c1) = [int(x) for x in input().split()]
(r2, c2) = [int(x) for x in input().split()]
grafo = []
visited = []
for i in range(n):
	tmp = []
	for j in range(n):
		tmp.append(False)
	visited.append(tmp)
for i in range(n):
	s = input()
	grafo.append(list(s))
adj = {}
for i in range(n):
	for j in range(n):
		adj[i, j] = []
		if j and grafo[i][j - 1] == '0':
			adj[i, j].append((i, j - 1))
		if j < n - 1 and grafo[i][j + 1] == '0':
			adj[i, j].append((i, j + 1))
		if i and grafo[i - 1][j] == '0':
			adj[i, j].append((i - 1, j))
		if i < n - 1 and grafo[i + 1][j] == '0':
			adj[i, j].append((i + 1, j))
s1 = set()
s2 = set()

def dfs(v, s):
	fila = deque()
	fila.append(v)
	visited[v[0]][v[1]] = True
	s.add(v)
	while fila:
		aux = fila.popleft()
		for e in adj[aux]:
			if not visited[e[0]][e[1]]:
				visited[e[0]][e[1]] = True
				fila.append(e)
				s.add(e)
dfs((r1 - 1, c1 - 1), s1)
dfs((r2 - 1, c2 - 1), s2)
final = []
for i in s1:
	for j in s2:
		co = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
		final.append(co)
print(min(final))


def add(ans, r, c):
	if cells[r][c] == '0':
		cells[r][c] = '1'
		rc = (r, c)
		ans.append(rc)

def dfs(r, c):
	ans = [(r, c)]
	for (r, c) in ans:
		if c != 1:
			add(ans, r, c - 1)
		if c != n:
			add(ans, r, c + 1)
		if r != 1:
			add(ans, r - 1, c)
		if r != n:
			add(ans, r + 1, c)
	return ans
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
res = 5000
cells = (['1'],) + tuple((['1'] + list(input()) for _ in range(n)))
dfs1 = dfs(r1, c1)
for (rs, cs) in dfs(r2, c2):
	for (rt, ct) in dfs1:
		res = min(res, (rs - rt) ** 2 + (cs - ct) ** 2)
print(res)


import math
from collections import deque, defaultdict
from sys import stdin, stdout
input = stdin.readline
listin = lambda : list(map(int, input().split()))
mapin = lambda : map(int, input().split())

def mark(grid_map, x, y):
	z = deque([(x, y)])
	k = [(x, y)]
	while z:
		(headx, heady) = z.popleft()
		if headx - 1 >= 0:
			if not grid_map[headx - 1][heady]:
				if grid[headx - 1][heady] == '0':
					z.append((headx - 1, heady))
					grid_map[headx - 1][heady] = True
					k.append((headx - 1, heady))
		if heady - 1 >= 0:
			if not grid_map[headx][heady - 1]:
				if grid[headx][heady - 1] == '0':
					z.append((headx, heady - 1))
					grid_map[headx][heady - 1] = True
					k.append((headx, heady - 1))
		if heady + 1 < n:
			if not grid_map[headx][heady + 1]:
				if grid[headx][heady + 1] == '0':
					z.append((headx, heady + 1))
					grid_map[headx][heady + 1] = True
					k.append((headx, heady + 1))
		if headx + 1 < n:
			if not grid_map[headx + 1][heady]:
				if grid[headx + 1][heady] == '0':
					z.append((headx + 1, heady))
					grid_map[headx + 1][heady] = True
					k.append((headx + 1, heady))
	return k
n = int(input())
(sx, sy) = mapin()
(fx, fy) = mapin()
sx -= 1
sy -= 1
fx -= 1
fy -= 1
grid = []
for _ in range(n):
	grid.append(input())
first = []
final = []
for _ in range(n):
	first.append([False] * n)
for _ in range(n):
	final.append([False] * n)
first = mark(first, sx, sy)
final = mark(final, fx, fy)
distmin = 10 ** 9
for i in first:
	for j in final:
		distmin = min(distmin, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(distmin)


from sys import stdin
n = int(stdin.readline().strip())
(x, y) = map(int, stdin.readline().strip().split())
(x1, y1) = map(int, stdin.readline().strip().split())
s = [stdin.readline().strip() for i in range(n)]
visited = [[False for i in range(n)] for i in range(n)]
lands = [[]]

def dfs(i, j):
	visited[i][j] = True
	lands[-1].append([i + 1, j + 1])
	a = i + 1
	b = i - 1
	c = j + 1
	d = j - 1
	if d >= 0 and (not visited[i][d]):
		if s[i][d] == '1':
			visited[i][d] = True
		else:
			dfs(i, d)
	if c < n and (not visited[i][c]):
		if s[i][c] == '1':
			visited[i][c] = True
		else:
			dfs(i, c)
	if b >= 0 and (not visited[b][j]):
		if s[b][j] == '1':
			visited[b][j] = True
		else:
			dfs(b, j)
	if a < n and (not visited[a][j]):
		if s[a][j] == '1':
			visited[a][j] = True
		else:
			dfs(a, j)
ans = 10 ** 10
dfs(x - 1, y - 1)
lands.append([])
dfs(x1 - 1, y1 - 1)
for i in lands[0]:
	for j in lands[1]:
		ans = min(ans, (i[0] - j[0]) ** 2 + (j[1] - i[1]) ** 2)
print(ans)


def parseint(s):
	return int(s) - 1
n = int(input())
(r1, c1) = map(parseint, input().split())
(r2, c2) = map(parseint, input().split())
graph = []
components = [[], []]
idx = 0
adj = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for _ in range(n):
	graph.append(list(input()))

def bfs(i, j):
	q = [(i, j)]
	while len(q):
		(vx, vy) = q.pop()
		graph[vx][vy] = '1'
		components[idx].append((vx, vy))
		for (x, y) in adj:
			ux = vx + x
			uy = vy + y
			if ux >= 0 and uy >= 0 and (ux < n) and (uy < n):
				if graph[ux][uy] == '0':
					q.append((ux, uy))
bfs(r1, c1)
if graph[r2][c2] == '1':
	print(0)
else:
	dist = 10 ** 5
	idx += 1
	bfs(r2, c2)
	for (x1, y1) in components[0]:
		for (x2, y2) in components[1]:
			dist = min(dist, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(dist)


from pprint import pprint
INF = 2 * 100 * 100 + 1

def dist(cur_ind, item):
	if abs(cur_ind[0] - item[0]) + abs(cur_ind[1] - item[1]) == 1:
		return 0
	else:
		return (cur_ind[0] - item[0]) ** 2 + (cur_ind[1] - item[1]) ** 2

def adj(i, j, n, arr):
	ans = []
	if i + 1 < n and arr[i + 1][j] == 0:
		ans.append([i + 1, j])
	if i - 1 > -1 and arr[i - 1][j] == 0:
		ans.append([i - 1, j])
	if j + 1 < n and arr[i][j + 1] == 0:
		ans.append([i, j + 1])
	if j - 1 > -1 and arr[i][j - 1] == 0:
		ans.append([i, j - 1])
	return ans
n = int(input())
(r1, c1) = map(int, input().split())
(r1, c1) = (r1 - 1, c1 - 1)
(r2, c2) = map(int, input().split())
(r2, c2) = (r2 - 1, c2 - 1)
arr = [[]] * n
for i in range(n):
	arr[i] = list(map(int, list(input())))
used = [[False for _ in range(n)] for _ in range(n)]
used[r1][c1] = True
q = [[r1, c1]]
clique1 = [[r1, c1]]
while len(q) > 0:
	next_v = q[0]
	q = q[1:]
	for item in adj(next_v[0], next_v[1], n, arr):
		if not used[item[0]][item[1]]:
			q.append(item)
			clique1.append(item)
		used[item[0]][item[1]] = True
if used[r2][c2]:
	print(0)
else:
	q = [[r2, c2]]
	clique2 = [[r2, c2]]
	used[r2][c2] = True
	while len(q) > 0:
		next_v = q[0]
		q = q[1:]
		for item in adj(next_v[0], next_v[1], n, arr):
			if not used[item[0]][item[1]]:
				q.append(item)
				clique2.append(item)
			used[item[0]][item[1]] = True
	ans = INF
	for item1 in clique1:
		for item2 in clique2:
			ans = min(ans, dist(item1, item2))
	print(ans)


from collections import deque
n = int(input())
(r1, c1) = map(int, input().split(' '))
(r2, c2) = map(int, input().split(' '))
s = []
e = [[False for i in range(n)] for i in range(n)]
for i in range(n):
	s.append(list(input()))
q = deque([[r1 - 1, c1 - 1]])
e[r1 - 1][c1 - 1] = True
c = 1
l = []
while len(q) != 0:
	c = 0
	(a, b) = (q[0][0], q[0][1])
	if a + 1 <= n - 1 and e[a + 1][b] == False and (s[a + 1][b] == '0'):
		if a + 1 == r2 - 1 and b == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a + 1, b])
		c = 1
		e[a + 1][b] = True
	if a - 1 >= 0 and e[a - 1][b] == False and (s[a - 1][b] == '0'):
		if a - 1 == r2 - 1 and b == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a - 1, b])
		c = 1
		e[a - 1][b] = True
	if b + 1 <= n - 1 and e[a][b + 1] == False and (s[a][b + 1] == '0'):
		if a == r2 - 1 and b + 1 == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a, b + 1])
		c = 1
		e[a][b + 1] = True
	if b - 1 >= 0 and e[a][b - 1] == False and (s[a][b - 1] == '0'):
		if a == r2 - 1 and b - 1 == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a, b - 1])
		c = 1
		e[a][b - 1] = True
	l.append(q.popleft())
q = deque([[r2 - 1, c2 - 1]])
e = [[False for i in range(n)] for i in range(n)]
e[r2 - 1][c2 - 1] = True
c = 1
m = []
while len(q) != 0:
	c = 0
	(a, b) = (q[0][0], q[0][1])
	if a + 1 <= n - 1 and e[a + 1][b] == False and (s[a + 1][b] == '0'):
		if a + 1 == r2 - 1 and b == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a + 1, b])
		c = 1
		e[a + 1][b] = True
	if a - 1 >= 0 and e[a - 1][b] == False and (s[a - 1][b] == '0'):
		if a - 1 == r2 - 1 and b == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a - 1, b])
		c = 1
		e[a - 1][b] = True
	if b + 1 <= n - 1 and e[a][b + 1] == False and (s[a][b + 1] == '0'):
		if a == r2 - 1 and b + 1 == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a, b + 1])
		c = 1
		e[a][b + 1] = True
	if b - 1 >= 0 and e[a][b - 1] == False and (s[a][b - 1] == '0'):
		if a == r2 - 1 and b - 1 == c2 - 1:
			print(0)
			exit(0)
		else:
			q.append([a, b - 1])
		c = 1
		e[a][b - 1] = True
	m.append(q.popleft())
mi = 10 ** 9
for i in l:
	for j in m:
		mi = min(mi, (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2)
print(mi)


def main():
	from collections import deque

	def in_range(r, c):
		return 0 <= r < n and 0 <= c < n
	n = int(input())
	(r1, c1) = [int(i) - 1 for i in input().split()]
	(r2, c2) = [int(i) - 1 for i in input().split()]
	s = [input() for _ in range(n)]
	v = [[0] * n for _ in range(n)]
	q = deque([(r1, c1)])
	v[r1][c1] |= 1
	while q:
		(x, y) = q.popleft()
		if in_range(x - 1, y) and s[x - 1][y] == '0' and (not v[x - 1][y] & 1):
			q.append((x - 1, y))
			v[x - 1][y] |= 1
		if in_range(x + 1, y) and s[x + 1][y] == '0' and (not v[x + 1][y] & 1):
			q.append((x + 1, y))
			v[x + 1][y] |= 1
		if in_range(x, y - 1) and s[x][y - 1] == '0' and (not v[x][y - 1] & 1):
			q.append((x, y - 1))
			v[x][y - 1] |= 1
		if in_range(x, y + 1) and s[x][y + 1] == '0' and (not v[x][y + 1] & 1):
			q.append((x, y + 1))
			v[x][y + 1] |= 1
	q = deque([(r2, c2)])
	v[r2][c2] |= 2
	while q:
		(x, y) = q.popleft()
		if in_range(x - 1, y) and s[x - 1][y] == '0' and (not v[x - 1][y] & 2):
			q.append((x - 1, y))
			v[x - 1][y] |= 2
		if in_range(x + 1, y) and s[x + 1][y] == '0' and (not v[x + 1][y] & 2):
			q.append((x + 1, y))
			v[x + 1][y] |= 2
		if in_range(x, y - 1) and s[x][y - 1] == '0' and (not v[x][y - 1] & 2):
			q.append((x, y - 1))
			v[x][y - 1] |= 2
		if in_range(x, y + 1) and s[x][y + 1] == '0' and (not v[x][y + 1] & 2):
			q.append((x, y + 1))
			v[x][y + 1] |= 2
	min_cost = float('inf')
	(a, b) = ([], [])
	for i in range(n):
		for j in range(n):
			if v[i][j] == 1:
				a.append((i, j))
			elif v[i][j] == 2:
				b.append((i, j))
			elif v[i][j] == 3:
				print(0)
				return
	for (i1, j1) in a:
		for (i2, j2) in b:
			min_cost = min(min_cost, (i1 - i2) ** 2 + (j1 - j2) ** 2)
	print(min_cost)
main()


import sys, math
from collections import defaultdict, Counter

def li():
	return list(map(int, sys.stdin.readline().split()))

def ls():
	return list(map(int, list(input())))

def la():
	return list(input())

def ii():
	return int(input())
n = ii()
(r1, c1) = li()
(r2, c2) = li()
graph = []
for _ in range(n):
	graph.append(la())
visited = [[False] * n for _ in range(n)]
minm = float('inf')

def dfs(x, y, points):
	points.append([x + 1, y + 1])
	visited[x][y] = True
	for (i, j) in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
		if 0 <= i + x < n and 0 <= j + y < n and (not visited[x + i][y + j]) and (graph[x + i][y + j] == '0'):
			points = dfs(x + i, y + j, points)
	return points
	return
S = dfs(r1 - 1, c1 - 1, [])
T = dfs(r2 - 1, c2 - 1, [])
for (x1, y1) in S:
	for (x2, y2) in T:
		minm = min(minm, (x1 - x2) ** 2 + (y1 - y2) ** 2)
print(minm)


def parseint(s):
	return int(s) - 1
n = int(input())
(r1, c1) = map(parseint, input().split())
(r2, c2) = map(parseint, input().split())
graph = []
visit = [[False for _ in range(n)] for _ in range(n)]
reps = [-1 for _ in range(n ** 2)]
components = {}

def getint(x, y):
	return x * n + y

def neighbors(x, y):
	s = set()
	up = (x, max(0, y - 1))
	down = (x, min(y + 1, n - 1))
	left = (max(0, x - 1), y)
	right = (min(x + 1, n - 1), y)
	s.add(up)
	s.add(down)
	s.add(left)
	s.add(right)
	if (x, y) in s:
		s.remove((x, y))
	return s

def sep(i, j):
	if visit[i][j] or graph[i][j] == 1:
		return
	else:
		idx = getint(i, j)
		components[idx] = set()
		q = []
		q.append((i, j))
		while q:
			v = q.pop()
			(vx, vy) = v
			visit[vx][vy] = True
			reps[getint(vx, vy)] = idx
			components[idx].add((vx, vy))
			for u in neighbors(vx, vy):
				(ux, uy) = u
				if visit[ux][uy] or graph[ux][uy] == 1:
					continue
				else:
					q.append(u)
for _ in range(n):
	l = list(map(int, list(input())))
	graph.append(l)
sep(r1, c1)
sep(r2, c2)
idx1 = getint(r1, c1)
idx2 = getint(r2, c2)
if reps[idx1] == reps[idx2]:
	print(0)
else:
	dist = 10 ** 5
	for (x1, y1) in components[reps[idx1]]:
		for (x2, y2) in components[reps[idx2]]:
			dist = min(dist, (x1 - x2) ** 2 + (y1 - y2) ** 2)
	print(dist)


n = int(input())
(r1, c1) = (int(x) for x in input().split())
(r1, c1) = (r1 - 1, c1 - 1)
(r2, c2) = (int(x) for x in input().split())
(r2, c2) = (r2 - 1, c2 - 1)
mat = []
for _ in range(n):
	row = input().strip()
	mat.append(row)

def nbrs(r, c):
	deltas = [(0, 1), (0, -1), (1, 0), (-1, 0)]
	nbrlist = []
	for d in deltas:
		newpos = (r + d[0], c + d[1])
		if newpos[0] < 0 or newpos[0] >= n or newpos[1] < 0 or (newpos[1] >= n):
			continue
		if mat[newpos[0]][newpos[1]] != '0':
			continue
		nbrlist.append(newpos)
	return nbrlist

def isnearwater(r, c):
	deltas = [(0, 1), (0, -1), (1, 0), (-1, 0)]
	for d in deltas:
		newpos = (r + d[0], c + d[1])
		if newpos[0] < 0 or newpos[0] >= n or newpos[1] < 0 or (newpos[1] >= n):
			continue
		if mat[newpos[0]][newpos[1]] != '0':
			return True
	return False

def connected(r, c):
	q = [(r, c)]
	closed = set()
	while q:
		current = q.pop()
		closed.add(current)
		for nbr in nbrs(current[0], current[1]):
			if nbr in closed:
				continue
			q.append(nbr)
			closed.add(nbr)
	return closed

def dist(pos1, pos2):
	(r1, c1) = pos1
	(r2, c2) = pos2
	return (r2 - r1) ** 2 + (c2 - c1) ** 2
space1 = connected(r1, c1)
if (r2, c2) in space1:
	print(0)
else:
	mincost = dist((r1, c1), (r2, c2))
	space2 = connected(r2, c2)
	for a1 in space1:
		if not isnearwater(a1[0], a1[1]):
			continue
		for a2 in space2:
			if not isnearwater(a2[0], a2[1]):
				continue
			mincost = min(mincost, dist(a1, a2))
	print(mincost)


from collections import deque

def floodfill(x, y, grid, mark):
	if grid[x][y] != '0':
		return
	n = len(grid)
	queue = deque()
	queue.append((x, y))
	while queue:
		(cx, cy) = queue[0]
		queue.popleft()
		if grid[cx][cy] == mark:
			continue
		grid[cx][cy] = mark
		for d in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
			(nx, ny) = (cx + d[0], cy + d[1])
			if 0 <= nx < n and 0 <= ny < n and (grid[nx][ny] == '0'):
				queue.append((nx, ny))

def main():
	n = int(input())
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	(r1, c1, r2, c2) = (r1 - 1, c1 - 1, r2 - 1, c2 - 1)
	grid = []
	for _ in range(n):
		grid.append(list(input()))
	floodfill(r1, c1, grid, '*')
	floodfill(r2, c2, grid, '-')
	if grid[r1][c1] == grid[r2][c2]:
		print(0)
	else:
		(pos1, pos2) = ([], [])
		for i in range(n):
			for j in range(n):
				if grid[i][j] == '*':
					pos1.append((i, j))
				elif grid[i][j] == '-':
					pos2.append((i, j))
		ret = float('inf')
		for (rs, cs) in pos1:
			for (rt, ct) in pos2:
				ret = min(ret, (rt - rs) ** 2 + (ct - cs) ** 2)
		print(int(ret))
main()


import math
import sys
sys.setrecursionlimit(2600)

class UnionFind:

	def __init__(self, num_elements):
		self.parent = list(range(num_elements))
		self.rank = [1] * num_elements

	def union(self, a, b):
		par_a = self.find(a)
		par_b = self.find(b)
		if par_a == par_b:
			return
		if self.rank[par_a] > self.rank[par_b]:
			self.parent[par_b] = par_a
			self.rank[par_a] = self.rank[par_a] + self.rank[par_b]
		else:
			self.parent[par_a] = par_b
			self.rank[par_b] = self.rank[par_a] + self.rank[par_b]

	def find(self, a):
		if self.parent[a] == a:
			return a
		par_a = self.find(self.parent[a])
		curr_parent = self.parent[a]
		if par_a != curr_parent:
			self.rank[curr_parent] -= self.rank[a]
			self.parent[a] = par_a
		return par_a
n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
arr = []
for i in range(n):
	arr.append(input())

def dfs():
	seen = set()
	directions = [(-1, 0), (0, -1), (0, 1), (1, 0)]
	uf = UnionFind(n * n)

	def find_index(i, j):
		return i * n + j

	def _dfs(i, j):
		if (i, j) in seen:
			return
		seen.add((i, j))
		if arr[i][j] == '1':
			return
		for direction in directions:
			(ni, nj) = (i + direction[0], j + direction[1])
			if ni >= 0 and ni < n and (nj >= 0) and (nj < n) and ((ni, nj) not in seen) and (arr[ni][nj] == '0'):
				uf.union(i * n + j, ni * n + nj)
				_dfs(ni, nj)
	for i in range(n):
		for j in range(n):
			_dfs(i, j)
	if uf.find(r1 * n + c1) == uf.find(r2 * n + c2):
		return 0
	parent1 = uf.find(r1 * n + c1)
	parent2 = uf.find(r2 * n + c2)
	min_distance = math.inf
	set_a = set()
	set_b = set()
	for i in range(n):
		for j in range(n):
			parent = uf.find(find_index(i, j))
			if parent == parent1:
				set_a.add((i, j))
			elif parent == parent2:
				set_b.add((i, j))
	for el1 in set_a:
		for el2 in set_b:
			dist = pow(el1[0] - el2[0], 2) + pow(el1[1] - el2[1], 2)
			min_distance = min(min_distance, dist)
	return min_distance
print(dfs())


import os, sys
from io import IOBase, BytesIO
py2 = round(0.5)
if py2:
	from future_builtins import ascii, filter, hex, map, oct, zip
	range = xrange
BUFSIZE = 8192

class FastIO(BytesIO):
	newlines = 0

	def __init__(self, file):
		self._file = file
		self._fd = file.fileno()
		self.writable = 'x' in file.mode or 'w' in file.mode
		self.write = super(FastIO, self).write if self.writable else None

	def _fill(self):
		s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
		self.seek((self.tell(), self.seek(0, 2), super(FastIO, self).write(s))[0])
		return s

	def read(self):
		while self._fill():
			pass
		return super(FastIO, self).read()

	def readline(self):
		while self.newlines == 0:
			s = self._fill()
			self.newlines = s.count(b'\n') + (not s)
		self.newlines -= 1
		return super(FastIO, self).readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.getvalue())
			(self.truncate(0), self.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		if py2:
			self.write = self.buffer.write
			self.read = self.buffer.read
			self.readline = self.buffer.readline
		else:
			self.write = lambda s: self.buffer.write(s.encode('ascii'))
			self.read = lambda : self.buffer.read().decode('ascii')
			self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import sys

class ostream:

	def __lshift__(self, a):
		sys.stdout.write(str(a))
		return self
cout = ostream()
endl = '\n'
import math
from collections import defaultdict
n = int(input())
(r, c) = map(int, input().split())
(k, l) = map(int, input().split())
r -= 1
c -= 1
k -= 1
l -= 1
mat = [[0 for i in range(n)] for i in range(n)]
for i in range(n):
	cc = str(input())
	for j in range(n):
		if cc[j] == '1':
			mat[i][j] = 1
zone = [[0 for i in range(n)] for i in range(n)]

def adj(i, j):
	res = []
	if i > 0 and mat[i - 1][j] == 0:
		res.append((i - 1, j))
	if j > 0 and mat[i][j - 1] == 0:
		res.append((i, j - 1))
	if j < n - 1 and mat[i][j + 1] == 0:
		res.append((i, j + 1))
	if i < n - 1 and mat[i + 1][j] == 0:
		res.append((i + 1, j))
	return res

def dfs(i, j, v):
	v = defaultdict(lambda : False)
	s = [(i, j)]
	g = []
	v[i, j] = True
	while s:
		(x, y) = s.pop()
		g.append((x, y))
		for (i, j) in adj(x, y):
			if v[i, j]:
				continue
			s.append((i, j))
			v[i, j] = True
			zone[i][j] = v
	return g
g1 = dfs(r, c, 1)
g2 = dfs(k, l, 2)
if zone[r][c] == 2:
	print(0)
	exit()

def dist(i, j, k, l):
	return (i - k) ** 2 + (j - l) ** 2
ans = float('INF')
for (i, j) in g1:
	for (x, y) in g2:
		ans = min(ans, dist(i, j, x, y))
print(ans)


n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = []
for i in range(n):
	aa = input()
	c = []
	for j in aa:
		c.append(int(j))
	a.append(c)
c = [[False for i in range(n)] for j in range(n)]
c[r1 - 1][c1 - 1] = True
while True:
	cnt = 0
	for i in range(n):
		for j in range(n):
			if c[i][j]:
				if i != 0:
					if a[i - 1][j] == 0 and (not c[i - 1][j]):
						c[i - 1][j] = True
						cnt += 1
				if i != n - 1:
					if a[i + 1][j] == 0 and (not c[i + 1][j]):
						c[i + 1][j] = True
						cnt += 1
				if j != 0:
					if a[i][j - 1] == 0 and (not c[i][j - 1]):
						c[i][j - 1] = True
						cnt += 1
				if j != n - 1:
					if a[i][j + 1] == 0 and (not c[i][j + 1]):
						c[i][j + 1] = True
						cnt += 1
	if cnt == 0:
		break
b = []
for i in range(n):
	for j in range(n):
		if c[i][j]:
			b.append([i + 1, j + 1])
c = [[False for i in range(n)] for j in range(n)]
c[r2 - 1][c2 - 1] = True
while True:
	cnt = 0
	for i in range(n):
		for j in range(n):
			if c[i][j]:
				if i != 0:
					if a[i - 1][j] == 0 and (not c[i - 1][j]):
						c[i - 1][j] = True
						cnt += 1
				if i != n - 1:
					if a[i + 1][j] == 0 and (not c[i + 1][j]):
						c[i + 1][j] = True
						cnt += 1
				if j != 0:
					if a[i][j - 1] == 0 and (not c[i][j - 1]):
						c[i][j - 1] = True
						cnt += 1
				if j != n - 1:
					if a[i][j + 1] == 0 and (not c[i][j + 1]):
						c[i][j + 1] = True
						cnt += 1
	if cnt == 0:
		break
d = []
for i in range(n):
	for j in range(n):
		if c[i][j]:
			d.append([i + 1, j + 1])
if b == d:
	print('0')
else:
	minm = 100000000
	for i in b:
		for j in d:
			ans = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
			if ans < minm:
				minm = ans
	print(minm)


n = int(input())
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
matrix = []
for i in range(n):
	matrix.append(list(map(str, input())))
visited = [[False for i in range(n)] for i in range(n)]
coor = [[1, 0], [0, 1], [-1, 0], [0, -1]]
(r1, c1, r2, c2) = (r1 - 1, c1 - 1, r2 - 1, c2 - 1)
q = []
q.append([r1, c1])
visited[r1][c1] = True
set1 = [[r1, c1]]
flag = 0
while len(q) != 0:
	(x, y) = (q[0][0], q[0][1])
	q.pop(0)
	for v in coor:
		(a, b) = (x + v[0], y + v[1])
		if a >= 0 and a < n and (b >= 0) and (b < n):
			if visited[a][b] == False and matrix[a][b] != '1':
				visited[a][b] = True
				if a == r2 and b == c2:
					flag = 1
				set1.append([a, b])
				q.append([a, b])
if flag == 1:
	print(0)
else:
	vis = [[False for i in range(n)] for i in range(n)]
	q = []
	q.append([r2, c2])
	visited[r2][c2] = True
	set2 = [[r2, c2]]
	f = 0
	while len(q) != 0:
		(x, y) = (q[0][0], q[0][1])
		q.pop(0)
		for v in coor:
			(a, b) = (x + v[0], y + v[1])
			if a >= 0 and a < n and (b >= 0) and (b < n):
				if visited[a][b] == False and matrix[a][b] != '1':
					visited[a][b] = True
					if a == r1 and b == c1:
						f = 1
					set2.append([a, b])
					q.append([a, b])
	if f == 1:
		print(0)
	else:
		cost = 10 ** 10
		for i in set1:
			for j in set2:
				(u, v) = (i[0], i[1])
				(x, y) = (j[0], j[1])
				val = (x - u) ** 2 + (y - v) ** 2
				cost = min(cost, val)
		print(cost)


gi = lambda : list(map(int, input().split()))
(n,) = gi()
(r, c) = gi()
(r1, c1) = gi()
grid = [input() for e in range(n)]
vis = [[0 for e in range(n)] for j in range(n)]
flag = 1

def dfs(x, y, comp):
	stack = [(x, y)]
	while stack:
		e = stack.pop()
		(x, y) = e
		if flag and x == r1 - 1 and (y == c1 - 1):
			print(0)
			exit()
		if x < 0 or x >= n or y < 0 or (y >= n) or (grid[x][y] == '1') or vis[x][y]:
			continue
		comp.append((x, y))
		vis[x][y] = 1
		stack.append((x + 1, y))
		stack.append((x - 1, y))
		stack.append((x, y + 1))
		stack.append((x, y - 1))

def dis(a, b):
	return abs(a[0] - b[0]) ** 2 + abs(a[1] - b[1]) ** 2
source = []
dest = []
dfs(r - 1, c - 1, source)
flag = 0
dfs(r1 - 1, c1 - 1, dest)
ans = 1000000000000
for e in source:
	for j in dest:
		if dis(e, j) < ans:
			ans = dis(e, j)
print(ans)


import sys
sys.setrecursionlimit(15000)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
graph = []
visiteds_by_source = {}
visiteds_by_target = {}
results = []
result = -1
for i in range(n):
	row = list(input())
	graph.append(row)

def dfs(x, y, visiteds):
	valid_x = x >= 0 and x < n
	valid_y = y >= 0 and y < n
	valid_point = valid_x and valid_y
	if valid_point and graph[x][y] == '0' and (not (x, y) in visiteds):
		visiteds[x, y] = True
		dfs(x - 1, y, visiteds)
		dfs(x, y - 1, visiteds)
		dfs(x + 1, y, visiteds)
		dfs(x, y + 1, visiteds)
	return

def get_answer(x1, y1, x2, y2):
	return (x1 - x2) ** 2 + (y1 - y2) ** 2
dfs(r1 - 1, c1 - 1, visiteds_by_source)
if (r2 - 1, c2 - 1) in visiteds_by_source:
	result = 0
else:
	dfs(r2 - 1, c2 - 1, visiteds_by_target)
	result = get_answer(r1, c1, r2, c2)
	for (x_source, y_source) in visiteds_by_source:
		for (x_target, y_target) in visiteds_by_target:
			answer = get_answer(x_source, y_source, x_target, y_target)
			result = min(result, answer)
print(result)


import os
import sys
from io import BytesIO, IOBase
from collections import defaultdict, deque, Counter, OrderedDict
import threading
(dx, dy) = ([1, -1, 0, 0], [0, 0, 1, -1])

def main():
	n = int(input())
	(r1, c1) = map(int, input().split())
	r1 -= 1
	c1 -= 1
	(r2, c2) = map(int, input().split())
	r2 -= 1
	c2 -= 1
	D = [input() for _ in range(n)]
	fill = [[-1] * n for _ in range(n)]
	land = []
	z = 0
	for i in range(n):
		for j in range(n):
			if fill[i][j] == -1 and D[i][j] == '0':
				fill[i][j] = z
				q = deque([[i, j]])
				island = [(i, j)]
				while q:
					(x, y) = q.popleft()
					for k in range(4):
						(nx, ny) = (x + dx[k], y + dy[k])
						if 0 <= nx < n and 0 <= ny < n and (D[nx][ny] == '0') and (fill[nx][ny] == -1):
							q.append([nx, ny])
							fill[nx][ny] = z
							island.append((nx, ny))
				land.append(island)
				z += 1
	a = fill[r1][c1]
	b = fill[r2][c2]
	ans = float('inf')
	for (x, y) in land[a]:
		for (nx, ny) in land[b]:
			ans = min((x - nx) ** 2 + (y - ny) ** 2, ans)
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


planet = {}
colors = {2: [], 3: []}
n = int(input())
(r1, c1) = [int(x) for x in input().split(' ')]
(r2, c2) = [int(x) for x in input().split(' ')]
for i in range(n + 2):
	planet.setdefault((0, i), -1)
	planet.setdefault((i, 0), -1)
	planet.setdefault((n + 1, i), -1)
	planet.setdefault((i, n + 1), -1)
for i in range(1, n + 1):
	row = input()
	for j in range(1, n + 1):
		planet.setdefault((i, j), int(row[j - 1]))
coada = []

def color_island(x, y, color):
	coada.append((x, y))
	planet[x, y] = color
	colors[color].append((x, y))
	while len(coada) != 0:
		move(coada[0][0], coada[0][1], color)

def move(x, y, color):
	if planet[x, y + 1] == 0:
		planet[x, y + 1] = color
		coada.append((x, y + 1))
		colors[color].append((x, y + 1))
	if planet[x, y - 1] == 0:
		planet[x, y - 1] = color
		coada.append((x, y - 1))
		colors[color].append((x, y - 1))
	if planet[x - 1, y] == 0:
		planet[x - 1, y] = color
		colors[color].append((x - 1, y))
		coada.append((x - 1, y))
	if planet[x + 1, y] == 0:
		planet[x + 1, y] = color
		coada.append((x + 1, y))
		colors[color].append((x + 1, y))
	coada.remove((x, y))
color_island(r2, c2, 2)
if planet[r1, c1] == 2:
	print(0)
else:
	color_island(r1, c1, 3)
	minimum = n * 1000000
	for i in colors[2]:
		for j in colors[3]:
			dist = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
			if dist < minimum:
				minimum = dist
	print(minimum)


from bisect import bisect_right as br
from bisect import bisect_left as bl
from collections import defaultdict
from itertools import *
import functools
import sys
import math
MAX = sys.maxsize
MAXN = 10 ** 6 + 10
MOD = 10 ** 9 + 7

def isprime(n):
	n = abs(int(n))
	if n < 2:
		return False
	if n == 2:
		return True
	if not n & 1:
		return False
	for x in range(3, int(n ** 0.5) + 1, 2):
		if n % x == 0:
			return False
	return True

def mhd(a, b, x, y):
	return abs(a - x) + abs(b - y)

def numIN():
	return map(int, sys.stdin.readline().strip().split())

def charIN():
	return sys.stdin.readline().strip().split()

def chk(x, y):
	print(x, '=', y)

def ncr(n, k):
	res = 1
	c = [0] * (k + 1)
	c[0] = 1
	for i in range(1, n + 1):
		for j in range(min(i, k), 0, -1):
			c[j] = (c[j] + c[j - 1]) % MOD
	return c[k]

def diff(a, b):
	return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2
n = int(input())
(r1, c1) = numIN()
(r2, c2) = numIN()
l = []
for _ in range(n):
	l.append(['*'] + [int(i) for i in input()] + ['*'])
te = [[-1 for i in range(n + 2)]]
l = te + l + te
d = defaultdict(list)
for i in range(1, n + 1):
	for j in range(1, n + 1):
		if l[i][j] == 0:
			if l[i][j + 1] == 0:
				d[i, j].append((i, j + 1))
				d[i, j + 1].append((i, j))
			if l[i][j - 1] == 0:
				d[i, j].append((i, j - 1))
				d[i, j - 1].append((i, j))
			if l[i + 1][j] == 0:
				d[i, j].append((i + 1, j))
				d[i + 1, j].append((i, j))
			if l[i - 1][j] == 0:
				d[i, j].append((i - 1, j))
				d[i - 1, j].append((i, j))
for i in d.keys():
	d[i] = list(set(d[i]))

def bfs(v):
	p = []
	vis = defaultdict(int)
	q = []
	q.append(v)
	vis[v] = 1
	while q:
		s = q.pop(0)
		p.append(s)
		for i in d[s]:
			if not vis[i]:
				vis[i] = 1
				q.append(i)
	return p
z = bfs((r1, c1))
y = bfs((r2, c2))
mn = MAX
for i in z:
	for j in y:
		mn = min(mn, diff(i, j))
print(mn)


n = int(input())
a = [int(x) - 1 for x in input().split()]
b = [int(x) - 1 for x in input().split()]
grid = []
for i in range(n):
	row = []
	inp = input()
	for j in range(n):
		row.append(int(inp[j]))
	grid.append(row)

def adjust(grid, p, r):
	stack = [p]
	while len(stack) > 0:
		(x, y) = stack.pop()
		grid[x][y] = r
		if x > 0 and grid[x - 1][y] == 0:
			stack.append([x - 1, y])
		if x < n - 1 and grid[x + 1][y] == 0:
			stack.append([x + 1, y])
		if y > 0 and grid[x][y - 1] == 0:
			stack.append([x, y - 1])
		if y < n - 1 and grid[x][y + 1] == 0:
			stack.append([x, y + 1])
adjust(grid, a, 2)
if grid[b[0]][b[1]] == 2:
	print(0)
else:
	adjust(grid, b, 3)
	coords_a = []
	coords_b = []
	for x in range(n):
		for y in range(n):
			if grid[x][y] == 2:
				coords_a.append([x, y])
			if grid[x][y] == 3:
				coords_b.append([x, y])
	mincost = None
	for (xa, ya) in coords_a:
		for (xb, yb) in coords_b:
			if mincost is None:
				mincost = (xa - xb) ** 2 + (ya - yb) ** 2
			else:
				mincost = min((xa - xb) ** 2 + (ya - yb) ** 2, mincost)
	print(mincost)


import sys
input = sys.stdin.readline
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
MAP = [input().strip() for i in range(n)]
from collections import deque
QUE = deque()
QUE.append([r1 - 1, c1 - 1])
START = []
check = [[0] * n for i in range(n)]
while QUE:
	(x, y) = QUE.pop()
	START.append([x, y])
	check[x][y] = 1
	for (z, w) in [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]]:
		if z < 0 or z >= n or w < 0 or (w >= n):
			continue
		if check[z][w] == 1 or MAP[z][w] == '1':
			continue
		QUE.append([z, w])
if [r2 - 1, c2 - 1] in START:
	print(0)
	sys.exit()
QUE = deque()
QUE.append([r2 - 1, c2 - 1])
GOAL = []
check = [[0] * n for i in range(n)]
while QUE:
	(x, y) = QUE.pop()
	GOAL.append([x, y])
	check[x][y] = 1
	for (z, w) in [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]]:
		if z < 0 or z >= n or w < 0 or (w >= n):
			continue
		if check[z][w] == 1 or MAP[z][w] == '1':
			continue
		QUE.append([z, w])
ANS = 10 ** 15
for (x, y) in START:
	for (z, w) in GOAL:
		if (x - z) ** 2 + (y - w) ** 2 < ANS:
			ANS = (x - z) ** 2 + (y - w) ** 2
print(ANS)


from collections import defaultdict as df
from sys import stdin
n = int(stdin.readline())
(r1, c1) = list(map(int, stdin.readline().split()))
(r2, c2) = list(map(int, stdin.readline().split()))
a = [[0] * n for i in range(n)]
d = df(list)
for j in range(n):
	s = input().rstrip()
	for r in range(n):
		a[j][r] = int(s[r])
for i in range(n):
	for j in range(n):
		if a[i][j] == 0:
			if i - 1 > 0:
				if a[i - 1][j] == 0:
					d[i, j].append((i - 1, j))
			if i + 1 < n:
				if a[i + 1][j] == 0:
					d[i, j].append((i + 1, j))
			if j - 1 >= 0:
				if a[i][j - 1] == 0:
					d[i, j].append((i, j - 1))
			if j + 1 < n:
				if a[i][j + 1] == 0:
					d[i, j].append((i, j + 1))
my_zero = []
visited = [[False] * n for i in range(n)]
visited[r1 - 1][c1 - 1] = True
s = []
s.append((r1 - 1, c1 - 1))
while len(s) > 0:
	f = s.pop(0)
	for i in d[f[0], f[1]]:
		if visited[i[0]][i[1]] == False:
			visited[i[0]][i[1]] = True
			s.append((i[0], i[1]))
if visited[r1 - 1][c1 - 1] == True and visited[r2 - 1][c2 - 1] == True:
	print(0)
	exit()
else:
	mini = float('inf')
	visited1 = [[False] * n for i in range(n)]
	visited1[r2 - 1][c2 - 1] = True
	s = []
	s.append((r2 - 1, c2 - 1))
	while len(s) > 0:
		f = s.pop(0)
		for i in d[f[0], f[1]]:
			if visited1[i[0]][i[1]] == False:
				visited1[i[0]][i[1]] = True
				s.append((i[0], i[1]))
	my_meow = []
	for i in range(n):
		for j in range(n):
			if visited1[i][j] == True:
				my_meow.append((i, j))
			if visited[i][j] == True:
				my_zero.append((i, j))
	for i in my_zero:
		for j in my_meow:
			mini = min(mini, (i[0] + 1 - (j[0] + 1)) ** 2 + (i[1] + 1 - (j[1] + 1)) ** 2)
	print(mini)


def bfs(u, v, a, n):
	cx = a.copy()
	cx[u - 1][v - 1] = 1
	q = []
	q.append((u, v))
	be = 0
	en = 0
	x = [0, -1, 0, 1]
	y = [1, 0, -1, 0]
	while be <= en:
		r = q[be][0]
		c = q[be][1]
		be = be + 1
		for i in range(4):
			if r + x[i] >= 1 and r + x[i] <= n and (c + y[i] >= 1) and (c + y[i] <= n):
				if cx[r + x[i] - 1][c + y[i] - 1] == 0:
					cx[r + x[i] - 1][c + y[i] - 1] = 1
					q.append((r + x[i], c + y[i]))
					en = en + 1
	return q

def main():
	n = int(input())
	(r1, c1) = list(map(int, input().split()))
	(r2, c2) = list(map(int, input().split()))
	s = ['' for i in range(n)]
	for i in range(n):
		s[i] = str(input())
	a = [[0] * n for index in range(n)]
	for i in range(n):
		for j in range(n):
			if s[i][j] == '1':
				a[i][j] = 1
			else:
				a[i][j] = 0
	q1 = bfs(r1, c1, a, n)
	q2 = bfs(r2, c2, a, n)
	res = 290000000
	for i in q1:
		for j in q2:
			res = min(res, int((i[1] - j[1]) ** 2 + (i[0] - j[0]) ** 2))
	print(res)
main()


import sys
try:
	sys.stdin = open('in.in', 'r')
	sys.stdout = open('out.out', 'w')
except:
	pass
n = int(input())
(stx, sty) = map(int, input().split())
stx -= 1
sty -= 1
(edx, edy) = map(int, input().split())
edx -= 1
edy -= 1
a = []
for i in range(n):
	a.append(input())
dsu = [i for i in range(n * n + 2)]

def Findfa(pos):
	if dsu[pos] == pos:
		return pos
	dsu[pos] = Findfa(dsu[pos])
	return dsu[pos]

def Unite(a, b):
	a = Findfa(a)
	b = Findfa(b)
	dsu[a] = b
ids = []
nowid = 0
for i in range(n):
	tid = []
	for j in range(n):
		nowid += 1
		tid.append(nowid)
	ids.append(tid)
for i in range(n):
	for j in range(n):
		if i != 0 and a[i - 1][j] == a[i][j] == '0':
			Unite(ids[i - 1][j], ids[i][j])
		if j != 0 and a[i][j - 1] == a[i][j] == '0':
			Unite(ids[i][j - 1], ids[i][j])
ans = 10000000000
stfa = Findfa(ids[stx][sty])
edfa = Findfa(ids[edx][edy])
if stfa == edfa:
	print(0)
	exit(0)
for i in range(n):
	for j in range(n):
		if Findfa(ids[i][j]) != stfa:
			continue
		for k in range(n):
			for l in range(n):
				if Findfa(ids[k][l]) != edfa:
					continue
				ans = min(ans, (k - i) * (k - i) + (l - j) * (l - j))
print(ans)


class UnionFind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [0] * n

	def Find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.Find(self.par[x])
			return self.par[x]

	def Unite(self, x, y):
		x = self.Find(x)
		y = self.Find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				self.par[y] += self.par[x]
				self.par[x] = y
			else:
				self.par[x] += self.par[y]
				self.par[y] = x
				if self.rank[x] == self.rank[y]:
					self.rank[x] += 1

	def Same(self, x, y):
		return self.Find(x) == self.Find(y)

	def Size(self, x):
		return -self.par[self.Find(x)]
import sys
import io, os
input = sys.stdin.readline
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
(r1, c1) = (r1 - 1, c1 - 1)
(r2, c2) = (r2 - 1, c2 - 1)
S = [input().rstrip() for i in range(n)]
uf = UnionFind(n ** 2)
for y in range(n):
	for x in range(n):
		if S[y][x] == '1':
			continue
		v = y * n + x
		for (dy, dx) in ((-1, 0), (1, 0), (0, 1), (0, -1)):
			(ny, nx) = (y + dy, x + dx)
			if 0 <= ny < n and 0 <= nx < n:
				if S[ny][nx] == '1':
					continue
				u = ny * n + nx
				uf.Unite(v, u)
if uf.Same(r1 * n + c1, r2 * n + c2):
	print(0)
	exit()
V = []
U = []
for i in range(n ** 2):
	if uf.Same(r1 * n + c1, i):
		V.append(i)
	if uf.Same(r2 * n + c2, i):
		U.append(i)
ans = 10 ** 18
for v in V:
	(y1, x1) = divmod(v, n)
	for u in U:
		(y2, x2) = divmod(u, n)
		temp = (x1 - x2) ** 2 + (y1 - y2) ** 2
		ans = min(ans, temp)
print(ans)


import sys
input = sys.stdin.readline

def pprint(mat):
	for r in mat:
		print(r)
from collections import deque

def solve(r1, c1, r2, c2, n, nav_mat):
	visited = [[0] * n for _ in range(n)]
	components = []
	for r in range(n):
		for c in range(n):
			if nav_mat[r][c] or visited[r][c]:
				continue
			visited[r][c] = 1
			dq = deque([(r, c)])
			component = set()
			while dq:
				(cr, cc) = dq.popleft()
				component.add((cr, cc))
				for (dr, dc) in ((cr + 1, cc), (cr - 1, cc), (cr, cc + 1), (cr, cc - 1)):
					if 0 <= dr < n and 0 <= dc < n and (not nav_mat[dr][dc]) and (not visited[dr][dc]):
						visited[dr][dc] = 1
						dq.append((dr, dc))
			components.append(component)
	for i in range(len(components)):
		if (r1, c1) in components[i]:
			start_component = i
		if (r2, c2) in components[i]:
			end_component = i
	if start_component == end_component:
		return 0
	best = float('inf')
	for (r1, c1) in components[start_component]:
		for (r2, c2) in components[end_component]:
			best = min(best, (r1 - r2) ** 2 + (c1 - c2) ** 2)
	return best
n = int(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
mat = [[0] * n for _ in range(n)]
for r in range(n):
	row = mat[r]
	for (c, v) in enumerate(input().rstrip()):
		if v == '1':
			row[c] = 1
print(solve(r1, c1, r2, c2, n, mat))


import sys
import math
import bisect
import heapq
from bisect import bisect_right
from sys import stdin, stdout
sys.setrecursionlimit(100000)

def get_ints_in_variables():
	return map(int, sys.stdin.readline().strip().split())

def get_int():
	return int(sys.stdin.readline())

def get_ints_in_list():
	return list(map(int, sys.stdin.readline().strip().split()))

def get_list_of_list(n):
	return [list(map(int, sys.stdin.readline().strip().split())) for _ in range(n)]

def get_string():
	return sys.stdin.readline().strip()

def myceil(x, y):
	return (x + y - 1) // y

def dfs(grid, n, i, j, visited):
	if i < 0 or i >= n or j < 0 or (j >= n):
		return
	if grid[i][j] or visited[i][j]:
		return
	visited[i][j] = True
	dfs(grid, n, i - 1, j, visited)
	dfs(grid, n, i + 1, j, visited)
	dfs(grid, n, i, j + 1, visited)
	dfs(grid, n, i, j - 1, visited)

def getLastPoint(visited):
	pnt = []
	for i in range(len(visited)):
		for j in range(len(visited)):
			if visited[i][j]:
				pnt.append([i + 1, j + 1])
	return pnt

def Solution(grid, n, s, e):
	visited = [[0 for _ in range(n)] for _ in range(n)]
	dfs(grid, n, s[0] - 1, s[1] - 1, visited)
	ps = getLastPoint(visited)
	visited = [[0 for _ in range(n)] for _ in range(n)]
	dfs(grid, n, e[0] - 1, e[1] - 1, visited)
	pl = getLastPoint(visited)
	ans = float('inf')
	for i in range(len(ps)):
		for j in range(len(pl)):
			a = ps[i][0] - pl[j][0]
			b = ps[i][1] - pl[j][1]
			tmp = a * a + b * b
			ans = min(ans, tmp)
	print(ans if ans != float('inf') else 0)

def main():
	n = get_int()
	s = get_ints_in_list()
	e = get_ints_in_list()
	grid = [[int(c) for c in get_string()] for _ in range(n)]
	Solution(grid, n, s, e)
main()


import sys
from math import *
from collections import defaultdict
inn = lambda : list(map(int, input().split()))
sys.setrecursionlimit(12000000)

def main():
	try:
		n = int(input())
		(r1, c1) = inn()
		r1 -= 1
		c1 -= 1
		(r2, c2) = inn()
		r2 -= 1
		c2 -= 1
		arr = []
		count = 0
		for i in range(n):
			c = []
			for j in input():
				if int(j) == 0:
					count += 1
				c.append(int(j))
			arr.append(c)
		visited = set()
		toVisit = [(r1, c1)]
		global minn
		minn = 999999
		connecteds = []

		def fs(x, y):
			if (x, y) not in visited:
				visited.add((x, y))
				connecteds.append((x + 1, y + 1))
				try:
					if arr[x][y] == 0:
						dist = (x - r2) ** 2 + (y - c2) ** 2
						if dist < minn:
							minn = dist
				except:
					pass
				try:
					if arr[x + 1][y] == 0:
						fs(x + 1, y)
				except:
					pass
				try:
					if arr[x][y + 1] == 0:
						fs(x, y + 1)
				except:
					pass
				try:
					if y - 1 >= 0:
						if arr[x][y - 1] == 0:
							fs(x, y - 1)
				except:
					pass
				try:
					if x - 1 >= 0:
						if arr[x - 1][y] == 0:
							fs(x - 1, y)
				except:
					pass
		fs(r1, c1)
		conn1 = list(connecteds)
		connecteds = []
		fs(r2, c2)
		conn2 = connecteds
		try:
			if conn2 and conn1:
				for i in conn1:
					for j in conn2:
						dist = dist = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
						if dist < minn:
							minn = dist
				print(minn)
			else:
				print('0')
		except:
			print('0')
	except:
		print('0')
try:
	main()
except:
	print('0')


n = int(input())
(r1, c1) = map(int, input().split())
(r1, c1) = (r1 - 1, c1 - 1)
(r2, c2) = map(int, input().split())
(r2, c2) = (r2 - 1, c2 - 1)
T = [[] for i in range(n)]
for i in range(n):
	a = list(input())
	T[i] = a
k = 0
G = [[] for i in range(n * n)]
for i in range(n):
	for j in range(n):
		if T[i][j] == '0':
			que = [(i, j, k)]
			while que:
				(x, y, d) = que.pop()
				G[d].append((x, y))
				T[x][y] = '1'
				for (dx, dy) in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
					(nx, ny) = (x + dx, y + dy)
					if 0 <= nx < n and 0 <= ny < n and (T[nx][ny] == '0'):
						T[nx][ny] = '1'
						que.append((nx, ny, d))
			k += 1
s = -1
e = -1
for k in range(n * n):
	if (r1, c1) in G[k]:
		s = k
	if (r2, c2) in G[k]:
		e = k
num = float('inf')
for (sx, sy) in G[s]:
	for (ex, ey) in G[e]:
		num = min(num, abs(sx - ex) ** 2 + abs(sy - ey) ** 2)
print(num)


import sys
sys.setrecursionlimit(10000)

def dfs(r1, c1, l1):
	if r1 < 1 or r1 > n or c1 < 1 or (c1 > n) or (l[r1 - 1][c1 - 1] == '1'):
		return
	if (r1, c1) in l1:
		return
	l1.append((r1, c1))
	dfs(r1 - 1, c1, l1)
	dfs(r1, c1 - 1, l1)
	dfs(r1, c1 + 1, l1)
	dfs(r1 + 1, c1, l1)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
l = []
for i in range(n):
	l.append(list(input()))
l2 = []
l3 = []
dfs(r1, c1, l2)
dfs(r2, c2, l3)
ans = float('INF')
for i in range(len(l2)):
	for j in range(len(l3)):
		a = abs(l2[i][0] - l3[j][0]) ** 2 + abs(l2[i][1] - l3[j][1]) ** 2
		if a < ans:
			ans = a
print(ans)


import sys
sys.setrecursionlimit(10000000)
n = int(input())
(r1, c1) = [int(j) for j in input().split()]
(r2, c2) = [int(j) for j in input().split()]
a = [[j for j in input()] for i in range(n)]
visited = [[0 for i in range(n)] for j in range(n)]
(p, q) = ([], [])
d = {}
for i in range(n):
	for j in range(n):
		if a[i][j] == '0':
			if i + 1 < n:
				if a[i + 1][j] == '0':
					if (i, j) not in d:
						d[i, j] = [(i + 1, j)]
					else:
						d[i, j].append((i + 1, j))
			if j + 1 < n:
				if a[i][j + 1] == '0':
					if (i, j) not in d:
						d[i, j] = [(i, j + 1)]
					else:
						d[i, j].append((i, j + 1))
			if i - 1 >= 0:
				if a[i - 1][j] == '0':
					if (i, j) not in d:
						d[i, j] = [(i - 1, j)]
					else:
						d[i, j].append((i - 1, j))
			if j - 1 >= 0:
				if a[i][j - 1] == '0':
					if (i, j) not in d:
						d[i, j] = [(i, j - 1)]
					else:
						d[i, j].append((i, j - 1))

def Explore(v, p):
	visited[v[0]][v[1]] = 1
	p.append((v[0] + 1, v[1] + 1))
	if v in d:
		for w in d[v]:
			if not visited[w[0]][w[1]]:
				Explore(w, p)
Explore((r1 - 1, c1 - 1), p)
if (r2, c2) in p:
	print(0)
	exit(0)
visited = [[0 for i in range(n)] for j in range(n)]
Explore((r2 - 1, c2 - 1), q)
min = 1000000000.0
for i in p:
	for j in q:
		dis = (i[0] - j[0]) * (i[0] - j[0]) + (i[1] - j[1]) * (i[1] - j[1])
		if dis < min:
			min = dis
print(min)


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions
from collections import deque, defaultdict, OrderedDict
from fractions import Fraction
from decimal import Decimal

def main():
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')

	def colour(f, arena, n):
		c = 0
		for a in range(n):
			for b in range(n):
				if arena[a][b] == '0':
					if a + 1 < n and arena[a + 1][b] == str(f):
						arena[a][b] = str(f)
						c = 1
					if a - 1 >= 0 and arena[a - 1][b] == str(f):
						arena[a][b] = str(f)
						c = 1
					if b + 1 < n and arena[a][b + 1] == str(f):
						arena[a][b] = str(f)
						c = 1
					if b - 1 >= 0 and arena[a][b - 1] == str(f):
						arena[a][b] = str(f)
						c = 1
		if c == 0:
			return 1
		else:
			return colour(f, arena, n)
	n = ri()
	(ra, ca) = ria()
	(rd, cd) = ria()
	arena = []
	for i in range(n):
		arena.append(list(rs()))
	f = 2
	for i in range(n):
		for j in range(n):
			if arena[i][j] == '0':
				arena[i][j] = str(f)
				l = colour(f, arena, n)
			f += 1
	if arena[ra - 1][ca - 1] == arena[rd - 1][cd - 1]:
		print(0)
	else:
		na = arena[ra - 1][ca - 1]
		nd = arena[rd - 1][cd - 1]
		d = 9999999999999999999999
		for i in range(n):
			for j in range(n):
				if arena[i][j] == na:
					for u in range(n):
						for v in range(n):
							if arena[u][v] == nd:
								d = min(d, (u - i) ** 2 + (v - j) ** 2)
		print(d)
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


import sys
from collections import deque
fast_reader = sys.stdin.readline
fast_writer = sys.stdout.write

def input():
	return fast_reader().strip()

def print(*argv):
	fast_writer(' '.join((str(i) for i in argv)))
	fast_writer('\n')
for _ in range(1):
	n = int(input())
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	r1 -= 1
	r2 -= 1
	c1 -= 1
	c2 -= 1
	l = []
	for i in range(n):
		pp = list(input())
		pp = [int(j) for j in pp]
		l.append(pp[:])
	l1 = []
	q1 = deque([(r1, c1)])
	visited = [[0 for i in range(n)] for j in range(n)]
	while len(q1) > 0:
		(x, y) = q1.popleft()
		if visited[x][y] == 1:
			continue
		else:
			visited[x][y] = 1
			l1.append((x, y))
			if x - 1 >= 0 and l[x - 1][y] == 0:
				q1.append((x - 1, y))
			if y - 1 >= 0 and l[x][y - 1] == 0:
				q1.append((x, y - 1))
			if x + 1 < n and l[x + 1][y] == 0:
				q1.append((x + 1, y))
			if y + 1 < n and l[x][y + 1] == 0:
				q1.append((x, y + 1))
	if (r2, c2) in l1:
		print(0)
		continue
	l2 = []
	q2 = deque([(r2, c2)])
	visited = [[0 for i in range(n)] for j in range(n)]
	while len(q2) > 0:
		(x, y) = q2.popleft()
		if visited[x][y] == 1:
			continue
		else:
			visited[x][y] = 1
			l2.append((x, y))
			if x - 1 >= 0 and l[x - 1][y] == 0:
				q2.append((x - 1, y))
			if y - 1 >= 0 and l[x][y - 1] == 0:
				q2.append((x, y - 1))
			if x + 1 < n and l[x + 1][y] == 0:
				q2.append((x + 1, y))
			if y + 1 < n and l[x][y + 1] == 0:
				q2.append((x, y + 1))
	ans = 2 ** 40
	for i in range(len(l1)):
		for j in range(len(l2)):
			(rs, cs) = l1[i]
			rs += 1
			cs += 1
			(rt, ct) = l2[j]
			rt += 1
			ct += 1
			ans = min(ans, (rs - rt) ** 2 + (cs - ct) ** 2)
	print(ans)


def dfs(x, y, n, a):
	stk = []
	stk.append([x, y])
	while len(stk) != 0:
		(i, j) = (stk[-1][0], stk[-1][1])
		stk.pop()
		visit[i][j] = 1
		a.append([i, j])
		if i < n - 1 and arr[i + 1][j] == '0' and (visit[i + 1][j] == 0):
			stk.append([i + 1, j])
		if j < n - 1 and arr[i][j + 1] == '0' and (visit[i][j + 1] == 0):
			stk.append([i, j + 1])
		if j > 0 and arr[i][j - 1] == '0' and (visit[i][j - 1] == 0):
			stk.append([i, j - 1])
		if i > 0 and arr[i - 1][j] == '0' and (visit[i - 1][j] == 0):
			stk.append([i - 1, j])
n = int(input())
(s1, e1) = map(int, input().split())
(s2, e2) = map(int, input().split())
s1 -= 1
e1 -= 1
s2 -= 1
e2 -= 1
arr = []
for i in range(n):
	s = input().strip('\n')
	arr.append(s)
visit = [0] * n
for i in range(n):
	visit[i] = [0] * n
two = []
dfs(s2, e2, n, two)
one = []
visit = [0] * n
for i in range(n):
	visit[i] = [0] * n
dfs(s1, e1, n, one)
ans = 999999999999999
for i in range(len(one)):
	for j in range(len(two)):
		if (one[i][0] - two[j][0]) ** 2 + (one[i][1] - two[j][1]) ** 2 < ans:
			ans = (one[i][0] - two[j][0]) ** 2 + (one[i][1] - two[j][1]) ** 2
print(ans)


import sys
sys.setrecursionlimit(1000000)
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
a = []
for _ in range(n):
	a.append(input())
a1 = []
a2 = []

def dfs1(i, j):
	if (i, j) in a1:
		return
	if max(i, j) >= n or min(i, j) < 0:
		return
	if a[i][j] == '1':
		return
	a1.append((i, j))
	dfs1(i - 1, j)
	dfs1(i + 1, j)
	dfs1(i, j - 1)
	dfs1(i, j + 1)

def dfs2(i, j):
	if (i, j) in a2:
		return
	if max(i, j) >= n or min(i, j) < 0:
		return
	if a[i][j] == '1':
		return
	a2.append((i, j))
	dfs2(i - 1, j)
	dfs2(i + 1, j)
	dfs2(i, j - 1)
	dfs2(i, j + 1)
dfs1(r1 - 1, c1 - 1)
dfs2(r2 - 1, c2 - 1)
if (r2, c2) in a1:
	print(0)
else:
	ans = 5000
	for i in a1:
		for j in a2:
			d = (i[0] - j[0]) ** 2 + (i[1] - j[1]) ** 2
			ans = min(d, ans)
	print(ans)


def solve():
	n = int(input())
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	m = []
	for i in range(n):
		m.append(list(input()))
	area1 = []
	area2 = []
	q = []
	q.append((r1, c1))
	try:
		while True:
			t = q.pop()
			tr = t[0]
			tc = t[1]
			if m[tr - 1][tc - 1] == '0':
				m[tr - 1][tc - 1] = '2'
				area1.append(t)
				if tr > 1:
					q.append((tr - 1, tc))
				if tr < n:
					q.append((tr + 1, tc))
				if tc > 1:
					q.append((tr, tc - 1))
				if tc < n:
					q.append((tr, tc + 1))
	except IndexError as e:
		pass
	if m[r2 - 1][c2 - 1] == '2':
		return 0
	q = []
	q.append((r2, c2))
	try:
		while True:
			t = q.pop()
			tr = t[0]
			tc = t[1]
			if m[tr - 1][tc - 1] == '0':
				m[tr - 1][tc - 1] = '2'
				area2.append(t)
				if tr > 1:
					q.append((tr - 1, tc))
				if tr < n:
					q.append((tr + 1, tc))
				if tc > 1:
					q.append((tr, tc - 1))
				if tc < n:
					q.append((tr, tc + 1))
	except IndexError as e:
		pass
	inf = 1 << 60
	best_sc = inf
	for t1 in area1:
		for t2 in area2:
			sc = (t2[0] - t1[0]) ** 2 + (t2[1] - t1[1]) ** 2
			if best_sc > sc:
				best_sc = sc
	return best_sc
ans = solve()
print(ans)


class Cell:

	def __init__(self, _r, _c):
		self.r = _r
		self.c = _c
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
n = int(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
graph = []
for i in range(n):
	line = input()
	graph.append(line)

def isValid(r, c):
	return r in range(n) and c in range(n)
visited = [[False for i in range(n)] for j in range(n)]

def dfs(start):
	res = []
	if graph[start.r][start.c] == '0':
		res.append(start)
	s = []
	visited[start.r][start.c] = True
	s.append(start)
	while len(s) > 0:
		u = s.pop()
		for i in range(4):
			row = u.r + dr[i]
			col = u.c + dc[i]
			if isValid(row, col) and graph[row][col] == '0' and (not visited[row][col]):
				visited[row][col] = True
				s.append(Cell(row, col))
				res.append(Cell(row, col))
	return res
start = dfs(Cell(r1 - 1, c1 - 1))
end = dfs(Cell(r2 - 1, c2 - 1))
dist = []
for i in range(len(start)):
	for j in range(len(end)):
		dist.append((start[i].r - end[j].r) ** 2 + (start[i].c - end[j].c) ** 2)
print(min(dist))