### BUGGY CODE ###

INF = float('inf')

def dijkstra_al(s, n, ALcost):
    '''
    n: 頂点の数、s: 始点
    AL_cost[head] = [(tail, cost), ..., (tail, cost)]
    cost存在しないときはinf
    '''
    import heapq

    fixed = [False] * n # 重み確定したかどうか
    nfixed = 0 # 確定した数
    vertex_cost = [INF] * n  # 始点sから各頂点への重み

    # 1. 始点に0を書き込む
    vertex_cost[s] = 0
    H = []  # (cost, vertex)のheap
    heapq.heappush(H, (0, s))

    while(H): # Hが空になるまで
        # 2. 未確定の地点の中からもっとも小さい値を持つ地点を1つ選び、その値を確定させる
        u_cost, u = heapq.heappop(H)
        if fixed[u]: continue  # 取り出した頂点がすでに決まっている（古い情報）
        fixed[u] = True
        nfixed += 1

        # 3. 2で確定した地点から直接繋がっていて、かつ未確定な地点に対し、
        #    重みを計算し、書き込まれている値より小さければ更新する
        for v, cost in ALcost[u]:
            if fixed[v]: continue
            newcost = u_cost + cost
            if newcost < vertex_cost[v]:
                vertex_cost[v] = newcost
                heapq.heappush(H, (newcost, v))

        # 4. 全ての地点が確定していれば終了。そうでなければ2に戻る
        if nfixed == n: break

    return vertex_cost


def rc_to_v(y, x):
    return y * W + x

H, W = [int(x) for x in input().split()]
sy, sx = [int(x) - 1 for x in input().split()]
gy, gx = [int(x) - 1 for x in input().split()]
S = [list(input()) for _ in range(H)]

AL = [[] for _ in range(H * W)]

for y in range(H):
    for x in range(W):
        if S[y][x] == '#':  continue

        for dy in range(-2, 3):
            for dx in range(-2, 3):
                ny = y + dy
                nx = x + dx
                if ny < 0 or H <= ny or nx < 0 or W <= nx:
                    continue
                if S[ny][nx] == '#':  # 行けない
                    continue
                if (dy, dx) in [(0, -1), (0, 1), (1, 0), (-1, 0)]:
                    AL[rc_to_v(y, x)].append((rc_to_v(ny, nx), 0))
                else:
                    AL[rc_to_v(y, x)].append((rc_to_v(ny, nx), 1))


cost = dijkstra_al(rc_to_v(sy, sx), H * W, AL)

ans = cost[rc_to_v(gy, gx)]
print(-1 if ans == INF else int(ans))

### FIXED CODE ###

import sys
input = sys.stdin.readline
INF = float('inf')

def dijkstra_al(s, n, ALcost):
    '''
    n: 頂点の数、s: 始点
    AL_cost[head] = [(tail, cost), ..., (tail, cost)]
    cost存在しないときはinf
    '''
    import heapq

    fixed = [False] * n # 重み確定したかどうか
    nfixed = 0 # 確定した数
    vertex_cost = [INF] * n  # 始点sから各頂点への重み

    # 1. 始点に0を書き込む
    vertex_cost[s] = 0
    H = []  # (cost, vertex)のheap
    heapq.heappush(H, (0, s))

    while(H): # Hが空になるまで
        # 2. 未確定の地点の中からもっとも小さい値を持つ地点を1つ選び、その値を確定させる
        u_cost, u = heapq.heappop(H)
        if fixed[u]: continue  # 取り出した頂点がすでに決まっている（古い情報）
        fixed[u] = True
        nfixed += 1

        # 3. 2で確定した地点から直接繋がっていて、かつ未確定な地点に対し、
        #    重みを計算し、書き込まれている値より小さければ更新する
        for v, cost in ALcost[u]:
            if fixed[v]: continue
            newcost = u_cost + cost
            if newcost < vertex_cost[v]:
                vertex_cost[v] = newcost
                heapq.heappush(H, (newcost, v))

        # 4. 全ての地点が確定していれば終了。そうでなければ2に戻る
        if nfixed == n: break

    return vertex_cost


def rc_to_v(y, x):
    return y * W + x

H, W = [int(x) for x in input().split()]
sy, sx = [int(x) - 1 for x in input().split()]
gy, gx = [int(x) - 1 for x in input().split()]
S = [list(input().strip()) for _ in range(H)]

AL = [[] for _ in range(H * W)]

for y in range(H):
    for x in range(W):
        if S[y][x] == '#':  continue

        for dy in range(-2, 3):
            for dx in range(-2, 3):
                ny = y + dy
                nx = x + dx
                if ny < 0 or H <= ny or nx < 0 or W <= nx:
                    continue
                if S[ny][nx] == '#':  # 行けない
                    continue
                if (dy, dx) in [(0, -1), (0, 1), (1, 0), (-1, 0)]:
                    AL[rc_to_v(y, x)].append((rc_to_v(ny, nx), 0))
                else:
                    AL[rc_to_v(y, x)].append((rc_to_v(ny, nx), 1))


cost = dijkstra_al(rc_to_v(sy, sx), H * W, AL)

ans = cost[rc_to_v(gy, gx)]
print(-1 if ans == INF else int(ans))