### BUGGY CODE ###

from collections import deque

def bfs():
    # すべての点を初期化
    wpCnt = [[int(10**10)] * m for i in range(n)]

    # 移動4方向のベクトル
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    sx = Cm-1
    sy = Cn-1

    que = deque([])
    que.append((sy, sx))
    wpCnt[sy][sx] = 0

    # キューが空になるまでループ
    while que:
        # キューの先頭を取り出す
        p = que.popleft()
        # 移動4方向をループ
        for i in range(4):
            # 移動した後の点を (nx, ny) とする
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            # 移動が可能かの判定
            if 0 <= nx < n and 0 <= ny < m and maze[nx][ny] != "#" and wpCnt[nx][ny] > wpCnt[p[0]][p[1]]:
                # 移動できるならキューに入れ、優先的に処理
                wpCnt[nx][ny] = wpCnt[p[0]][p[1]]
                que.appendleft((nx, ny))

        # ワープ方向をループ
        for i in range(-2,3):
            for j in range(-2,3):
                # ワープした後の点を (nxw, nyw) とする
                nxw = p[0] + i
                nyw = p[1] + j

                # ワープが可能かの判定
                if 0 <= nxw < n and 0 <= nyw < m and maze[nxw][nyw] != "#" and 0 <= p[1] < m and 0 <= p[0] < n and wpCnt[nxw][nyw] > wpCnt[p[0]][p[1]] + 1 :
                    # ワープできるならキューに入れる
                    # print(nyw,nxw, p[0],p[1], i,j)
                    wpCnt[nxw][nyw] = wpCnt[p[0]][p[1]] + 1
                    que.append((nxw, nyw))
    return wpCnt

n, m = map(int, input().split())
Cn,Cm = map(int, input().split())
Dn,Dm = map(int, input().split())
maze = [list(input()) for _ in range(n)]

ans = bfs()

# print(ans)
if ans[Dn-1][Dm-1] == 10**10:
    print(-1)
else:
    print(ans[Dn-1][Dm-1])

### FIXED CODE ###

from collections import deque

def bfs():
    # すべての点を初期化
    wpCnt = [[int(10**10)] * m for i in range(n)]

    # 移動4方向のベクトル
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    sx = Cm-1
    sy = Cn-1

    que = deque([])
    que.append((sy, sx))
    wpCnt[sy][sx] = 0

    # キューが空になるまでループ
    while que:
        # キューの先頭を取り出す
        p = que.popleft()
        # 移動4方向をループ
        for i in range(4):
            # 移動した後の点を (nx, ny) とする
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            # 移動が可能かの判定
            if 0 <= nx < n and 0 <= ny < m and maze[nx][ny] != "#" and wpCnt[nx][ny] > wpCnt[p[0]][p[1]]:
                # 移動できるならキューに入れ、優先的に処理
                wpCnt[nx][ny] = wpCnt[p[0]][p[1]]
                que.appendleft((nx, ny))

        # ワープ方向をループ
        for i in range(-2,3):
            for j in range(-2,3):
                # ワープした後の点を (nxw, nyw) とする
                nxw = p[0] + i
                nyw = p[1] + j

                # ワープが可能かの判定
                if 0 <= nxw < n and 0 <= nyw < m and maze[nxw][nyw] != "#" and 0 <= p[1] < m and 0 <= p[0] < n and wpCnt[nxw][nyw] > wpCnt[p[0]][p[1]] + 1 :
                    # ワープできるならキューに入れる
                    # print(nyw,nxw, p[0],p[1], i,j)
                    wpCnt[nxw][nyw] = wpCnt[p[0]][p[1]] + 1
                    que.append((nxw, nyw))
    return wpCnt

n, m = map(int, input().split())
Cn,Cm = map(int, input().split())
Dn,Dm = map(int, input().split())
maze = [list(input()) for _ in range(n)]

ans = bfs()

# print(ans)
if ans[Dn-1][Dm-1] == 10**10:
    print(-1)
else:
    print(ans[Dn-1][Dm-1])