### BUGGY CODE ###

from heapq import heapify, heappop, heappush, heappushpop
from collections import deque
import sys
input = sys.stdin.readline

INF = 1e10

class PriorityQueue:
    """
    優先度付きキューの
    """
    def __init__(self, heap):
        self.heap = heap
        heapify(self.heap)
    
    def push(self, item):
        heappush(self.heap, item)
    
    def pop(self):
        return heappop(self.heap)
    
    def pushpop(self, item):
        return heappushpop(self.heap, item)
    
    def __call__(self):
        return self.heap
    
    def __len__(self):
        return len(self.heap)
    
    

def dijkstra(adj, sx, sy):
    Color = [[0]*(W+2) for _ in range(H+2)] # 0: 未訪問 1: Seen 2: Visited
    D = [[INF]*(W+2) for _ in range(H+2)] #始点からの距離(重み)
    # P = [None]*N #親

    D[sx][sy] = 0
    # P[s] = None
    PQ = PriorityQueue([(0, sx, sy)]) #(Cost, Node)を格納し、PQにする。

    while PQ: # PQに候補がある限り

        min_cost, ux, uy = PQ.pop() # 最小コストなノードu

        Color[ux][uy] = 1 # uをVisitedに。

        if D[ux][uy] < min_cost:
            # 更新の必要なし.
            continue

        for adj_x, adj_y, adj_w in adj[(ux, uy)]:
            if not Color[adj_x][adj_y]: #訪問済みでないなら
                if D[ux][uy] + adj_w < D[adj_x][adj_y]: #最小コストを更新できるなら、
                    D[adj_x][adj_y] = D[ux][uy] + adj_w
                    # P[adj_idx] = u
                    # PQに(隣接要素のコスト, 隣接要素の番号)を容れる
                    PQ.push((D[adj_x][adj_y], adj_x, adj_y))
                    
    
    return D


H,W=map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())

S = [["#"]*(W+2) for _ in range(H+2)]
for i in range(1,1+H):
    tmp=list(input())
    for j in range(1,1+W):
        S[i][j]=tmp[j-1]

idxs = []

for row in range(1, H+1):
    for col in range(1, W+1):
        if S[row][col] == ".":
            idxs.append((row, col))

dxdy = [(0, 1), (0, -1), (1, 0), (-1, 0)]
graph = {idx: deque() for idx in idxs}
for x in range(1, H+1):
    for y in range(1, W+1):
        if S[x][y] == "#":
            continue
        idxs.append((x, y))
        for dx, dy in dxdy:
            if S[x+dx][y+dy] == ".":
                graph[(x, y)].append((x+dx, y+dy, 0))
                

for idx in idxs:
    x = idx[0]
    y = idx[1]
    for dx in range(-2, 3):
        for dy in range(-2, 3):
            if x+dx < 1 or x+dx>H or y+dy<1 or y+dy>W:
                continue
            if S[x+dx][y+dy] == ".":
                graph[idx].append((x+dx, y+dy, 1))

D = dijkstra(graph, ch, cw)
if D[dh][dw] == INF:
    print(-1)
else:
    print(D[dh][dw])

### FIXED CODE ###

import heapq
INF = 1e7
H,W=map(int, input().split())
sx, sy = map(int, input().split())
dh, dw = map(int, input().split())
sx -= 1
sy -= 1
S = [input() for _ in range(H)]
D = [[INF]*(W) for _ in range(H)] #始点からの距離(重み)
D[sx][sy] = 0
PQ = [(0, (sx, sy))]
heapq.heapify(PQ)
while PQ: # PQに候補がある限り
    _, (ux, uy) = heapq.heappop(PQ) # 最小コストなノードu
    for dx in range(-2, 3):
        for dy in range(-2, 3):
            xx, yy = ux+dx, uy+dy
            if 0 <= xx < H and 0 <= yy < W and S[xx][yy]==".":
                is_not_neighbor = int(abs(dx) + abs(dy) != 1)
                # neighborでなければコストが1増える
                if D[ux][uy] + is_not_neighbor < D[xx][yy]:
                    D[xx][yy] = D[ux][uy] + is_not_neighbor
                    heapq.heappush(PQ, (D[xx][yy], (xx, yy)))
if D[dh-1][dw-1] >= INF:
    print(-1)
else:
    print(D[dh-1][dw-1])