### BUGGY CODE ###

from collections import deque
H, W = map(int, input().split())
sy, sx = map(int, input().split())
gy, gx = map(int, input().split())

field = [[c for c in input()] for i in range(H)]
movement = ((1, 0), (-1, 0), (0, 1), (0, -1))
def main():
    clusters = []
    sg = [-1, -1]
    c = 0
    checked = set()
    for y in range(H):
        for x in range(W):
            if (x, y) in checked or field[y][x] == '#':
                continue
            visited = set()
            queue = [(x, y)]
            while queue:
                now_x, now_y = queue.pop()
                if (now_x, now_y) in visited:
                    continue
                visited.add((now_x, now_y))
                for dx, dy in movement:
                    nx, ny = now_x+dx, now_y+dy
                    if (nx, ny) not in visited and 0<=nx<W and 0<=ny<H and field[ny][nx]=='.':
                        queue.append((nx, ny))
            if (sx-1, sy-1) in visited:
                sg[0] = c
            if (gx-1, gy-1) in visited:
                sg[1] = c
            checked = checked | visited
            clusters.append(sorted(list(visited)))
            c+=1

    def nearp(c1, c2):
        min1, max1 = c1[0][0], c1[-1][0]
        min2, max2 = c2[0][0], c2[-1][0]
        if max2 + 2 < min1 or max1 + 2 < min2:
            return False
        
        for x1, y1 in c1:
            for x2, y2 in c2:
                if abs(x1 - x2) < 3:
                    if abs(y1 - y2) < 3:
                        return True
        
        return False

    path = {i:[] for i in range(len(clusters))}

    for i in range(len(clusters)-1):
        for j in range(i+1, len(clusters)):
            if nearp(clusters[i], clusters[j]):
                path[i].append(j)
                path[j].append(i)

    start, goal = sg
    visited = set()
    queue = deque()
    queue.append((start, 0))
    result = -1
    while queue:
        now, dist = queue.popleft()
        if now == goal:
            result = dist
            break
        if now in visited:
            continue
        visited.add(now)
        for nxt in path[now]:
            if nxt not in visited:
                queue.append((nxt, dist+1))

    print(result)

if __name__ == '__main__':
    main()


### FIXED CODE ###

def main():
    H, W = map(int, input().split())

    y, x = map(int, input().split())
    start = (x+1, y+1)

    y, x = map(int, input().split())
    goal = (x+1, y+1)

    dist_table = [[-2] * (W+4)]
    dist_table.append([-2] * (W+4))
    for _ in range(H):
        row = '##' + input() + '##'
        row = [-1 if c == '.' else -2 for c in row]
        dist_table.append(row)
    dist_table.append([-2] * (W+4))
    dist_table.append([-2] * (W+4))



    sx, sy = start
    dist_table[sy][sx] = 0

    move1 = ((-1, 0), (1, 0), (0, 1), (0, -1))
    move2 = ((-2, -2), (-2, -1), (-2, 0), (-2, 1), (-2, 2),\
            (-1, -2), (-1, -1), (-1, 1), (-1, 2),\
            (0, -2), (0, 2),\
            (1, -2), (1, -1), (1, 1), (1, 2),\
            (2, -2), (2, -1), (2, 0), (2, 1), (2, 2))

    queue1 = [start]
    queue2 = []

    while queue1:
        now_x, now_y = queue1.pop()
        if (now_x, now_y) == goal:
            break
        queue2.append((now_x, now_y))
        dist = dist_table[now_y][now_x]
        for dx, dy in move1:
            tx, ty = now_x + dx, now_y + dy
            if dist_table[ty][tx] == -1:
                dist_table[ty][tx] = dist
                queue1.append((tx, ty))
        if len(queue1) == 0:
            while queue2:
                now_x, now_y = queue2.pop()
                dist = dist_table[now_y][now_x]
                for dx, dy in move2:
                    tx, ty = now_x + dx, now_y + dy
                    if dist_table[ty][tx] == -1:
                        dist_table[ty][tx] = dist + 1
                        queue1.append((tx, ty))
    gx, gy = goal
    print(dist_table[gy][gx])

if __name__ == '__main__':
    main()