### BUGGY CODE ###

from collections import deque
def main():
    H, W = map(int, input().split())

    sy, sx = map(int, input().split())
    start = (sx-1, sy-1)
    gy, gx = map(int, input().split())
    goal = (gx-1, gy-1)
    field = [[c for c in input()] for i in range(H)]

    visited = set()
    queue = deque()
    queue.append((start, 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))

    result = -1
    while queue:
        now_pos, dist = queue.popleft()
        if now_pos in visited:
            continue
        visited.add(now_pos)

        if now_pos == goal:
            result = dist
            break

        now_x, now_y = now_pos

        for dx, dy in move1:
            nxt_x, nxt_y = now_x + dx, now_y + dy
            if (nxt_x, nxt_y) in visited or not(0<=nxt_x<W and 0<=nxt_y<H) or field[nxt_y][nxt_x]=='#':
                continue
            queue.appendleft(((nxt_x, nxt_y), dist))
        
        for dx, dy in move2:
            nxt_x, nxt_y = now_x + dx, now_y + dy
            if (nxt_x, nxt_y) in visited or not(0<=nxt_x<W and 0<=nxt_y<H) or field[nxt_y][nxt_x]=='#':
                continue
            queue.append(((nxt_x, nxt_y), 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()