### BUGGY CODE ###

from sys import stdin, setrecursionlimit
from collections import Counter, deque, defaultdict
from heapq import heapify, heappush, heappop
from math import floor, ceil
from bisect import bisect_left
from itertools import combinations
setrecursionlimit(100000)

INF = int(1e10)
MOD = int(1e9 + 7)

dh = [0, 0, 1, -1]
dw = [1, -1, 0, 0]

class UnionFind(object):
    def __init__(self, n):
        self.n = n
        self.par = [-1] * 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:
            return False
        else:
            if self.par[x] > self.par[y]:
                x, y = y, x
            self.par[x] += self.par[y]
            self.par[y] = x
            return True

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

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

    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.par) if x < 0]

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

dh = [0, 0, 1, -1]
dw = [1, -1, 0, 0]

def main():
    from builtins import int, map
    H, W = map(int, input().split())
    Ch, Cw = map(int, input().split())
    Dh, Dw = map(int, input().split())
    Ch, Cw = Ch - 1, Cw - 1
    Dh, Dw = Dh - 1, Dw - 1
    S = [list(input()) for _ in range(H)]

    ncon_num = 0
    nodes = []
    idx = {}
    groups = {}
    for h in range(H):
        for w in range(W):
            if S[h][w] == '.':
                idx[(h, w)] = len(nodes)
                groups[h, w] = None
                nodes.append((h, w))
    N = len(nodes)
    uf = UnionFind(N)

    for h in range(H):
        for w in range(W):
            if S[h][w] == '#': continue
            I = idx[h, w]
            for i in range(4):
                nnh, nnw = h + dh[i], w + dw[i]
                if 0 <= nnh < H and 0 <= nnw < W and S[nnh][nnw] != '#':
                    J = idx[nnh, nnw]
                    uf.unite(I, J)

    for h in range(H):
        for w in range(W):
            if S[h][w] == '#': continue
            I = idx[h, w]
            # print(I, uf.members(I))
            if groups[nodes[I]] is None:
                groups[nodes[I]] = ncon_num
                for k in uf.members(I):
                    groups[nodes[k]] = ncon_num
                ncon_num += 1

    if ncon_num == 1:
        print(0)
        exit()

    ncon = len(set(groups.values()))
    start_con, goal_con = groups[Ch, Cw], groups[Dh, Dw]
    # print(ncon, start_con, goal_con)
    # print(groups)
    
    dist_mat = [[float("inf")] * ncon for _ in range(ncon)]
    for k in range(ncon):
        dist_mat[k][k] = 0
    for h in range(H):
        for w in range(W):
            if S[h][w] == '#': continue
            I = idx[h, w]
            for ddh in range(-2, 3):
                for ddw in range(-2, 3):
                    nnh, nnw = h + ddh, w + ddw
                    if 0 <= nnh < H and 0 <= nnw < W and S[nnh][nnw] != '#':
                        J = idx[nnh, nnw]
                        if I != J:
                            # print(I, J, groups[nodes[I]], groups[nodes[J]], uf.same(I, J))
                            if not uf.same(I, J):
                                di = groups[nodes[I]]
                                dj = groups[nodes[J]]
                                dist_mat[di][dj] = 1

    # 作成したグラフでDijkstra
    dist = [float("inf")] * ncon
    dist[start_con] = 0
    queue = [(0, start_con)]
    while queue:
        dc, c = heappop(queue)
        if dist[c] < dc:
            continue

        for cc in range(ncon):
            cost = dist_mat[c][cc]
            if dist != float("inf") and dist[cc] > dist[c] + cost:
                dist[cc] = dist[c] + cost
                heappush(queue, (dist[cc], cc))

    if dist[goal_con] == float("inf"):
        print(-1)
    else:
        print(dist[goal_con])


if __name__ == '__main__':
    main()


### FIXED CODE ###

from collections import deque
INF = int(1e10)

def main():
    from builtins import int, map
    H, W = map(int, input().split())
    Ch, Cw = map(lambda x: int(x) - 1, input().split())
    Dh, Dw = map(lambda x: int(x) - 1, input().split())
    S = [input() for _ in range(H)]

    # dist = defaultdict(lambda: float("inf"))
    dist = [[float("inf")] * W for _ in range(H)]
    queue = deque([(Ch, Cw, 0)])

    while queue:
        (h, w, d) = queue.popleft()

        if dist[h][w] == float("inf") or dist[h][w] > d:
            dist[h][w] = d
            
            # 5x5-grid
            for ddh in range(-2, 3):
                for ddw in range(-2, 3):
                    nh, nw = h + ddh, w + ddw
                    if 0 <= nh < H and 0 <= nw < W and S[nh][nw] == '.':
                        # cost-0 move
                        if abs(ddh) + abs(ddw) <= 1:
                            queue.appendleft((nh, nw, d))
                        # cost-1 move
                        else:
                            queue.append((nh, nw, d + 1))

    if dist[Dh][Dw] == float("inf"):
        print(-1)
    else:
        print(dist[Dh][Dw])

if __name__ == '__main__':
    main()