### BUGGY CODE ###

import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    H, W = LI()
    Ch, Cw = LI_()
    Dh, Dw = LI_()
    S = [list(SS()) for _ in range(H)]

    d = ((1, 0), (0, 1), (-1, 0), (0, -1)) 
    color = 0

    def dfs(cy, cx, tmp):
        S[cy][cx] = color
        tmp.add((cy, cx))
        for dy, dx in d:
            ny = cy + dy
            nx = cx + dx
            if 0 <= ny < H and 0 <= nx < W and S[ny][nx] == '.':
                dfs(ny, nx, tmp)

    # 連結成分
    # 連結成分でないところに対してはワープが必要だが、ワープすれば行けるとは保証できない
    # ワープありでの連結成分を調べる
    group_C = -1
    group_D = -1
    con = []
    for i, j in itertools.product(range(H), range(W)):
        if S[i][j] == '.':
            tmp = set()
            dfs(i, j, tmp)
            color += 1
            con.append(tmp)

    # for i in S:
    #     print(i)
    for i in range(len(con)):
        if (Ch, Cw) in con[i]:
            group_C = i
        if (Dh, Dw) in con[i]:
            group_D = i

    # print(group_C, group_D)

    G = [set() for _ in range(len(con))]

    for i, j in itertools.product(range(H), range(W)):
        if S[i][j] != '#':
            for dy, dx in itertools.product(range(-2, 3), repeat=2):
                ny = i + dy
                nx = j + dx
                if 0 <= ny < H and 0 <= nx < W and S[ny][nx] != '#':
                    if S[ny][nx] != S[i][j]:
                        G[S[i][j]].add(S[ny][nx])
    # print(G)

    ans = [INF]
    def dfs2(c, path):
        if c == group_D:
            ans[0] = min(len(path) - 1, ans[0])
        else:
            for n in G[c]:
                if n not in path:
                    path.append(n)
                    dfs2(n, path)
                    path.pop()

    dfs2(group_C, [group_C])

    if ans[0] == INF:
        print(-1)
    else:
        print(ans[0])

if __name__ == '__main__':
    resolve()


### FIXED CODE ###

import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    H, W = LI()
    Ch, Cw = LI_()
    Dh, Dw = LI_()
    S = [SS() for _ in range(H)]

    d = ((1, 0), (0, 1), (-1, 0), (0, -1)) 
    dist = [[INF] * W for _ in range(H)]
    que = collections.deque()
    que.append((Ch, Cw, 0))
    dist[Ch][Cw] = 0
    while que:
        cy, cx, cost = que.popleft()
        for dy, dx in d:
            ny = cy + dy
            nx = cx + dx
            if 0 <= ny < H and 0 <= nx < W and S[ny][nx] == '.' and cost < dist[ny][nx] :
                dist[ny][nx] = cost
                que.appendleft((ny, nx, cost))
        for dy, dx in itertools.product(range(-2, 3), repeat=2):
            ny = cy + dy
            nx = cx + dx
            if 0 <= ny < H and 0 <= nx < W and S[ny][nx] == '.' and cost + 1 < dist[ny][nx] :
                dist[ny][nx] = cost + 1
                que.append((ny, nx, cost + 1))

    if dist[Dh][Dw] == INF:
        print(-1)
    else:
        print(dist[Dh][Dw])

if __name__ == '__main__':
    resolve()