### BUGGY CODE ###

import heapq
import math

H, W = map(int, input().split())
Ch, Cw = map(lambda x: int(x) - 1, input().split())
Dh, Dw = map(lambda x: int(x) - 1, input().split())

tobool = lambda s: s == "#"

S = [
  list(map(tobool, input())) for _ in range(H)
]
visited_m = [[False for w in range(W) ] for h in range(H)]
cost_m = [[math.inf for w in range(W) ] for h in range(H)]

def enum_moveA(Ch, Cw):
  return [(Ch-1, Cw), (Ch+1, Cw), (Ch, Cw-1), (Ch, Cw+1)]

def enum_moveB(Ch, Cw):
  return [
    (Ch-2, Cw-2), (Ch-2, Cw-1), (Ch-2, Cw), (Ch-2, Cw+1), (Ch-2, Cw+2),
    (Ch-1, Cw-2), (Ch-1, Cw-1), (Ch-1, Cw+1), (Ch-1, Cw+2),
    (Ch, Cw-2), (Ch, Cw+2),
    (Ch+1, Cw-2), (Ch+1, Cw-1), (Ch+1, Cw+1), (Ch+1, Cw+2),
    (Ch+2, Cw-2), (Ch+2, Cw-1), (Ch+2, Cw), (Ch+2, Cw+1), (Ch+2, Cw+2),
  ]

heap = []
heapq.heappush(heap, (0, Ch, Cw))
while True:
  if len(heap) == 0:
    break
  visited_m[Ch][Cw] = True
  c_cost, Ch, Cw = heapq.heappop(heap)
  if Ch == Dh and Cw == Dw:
    break
  for h, w in enum_moveA(Ch, Cw):
    if 0 <= h <H and 0 <= w <W:
      tmp_cost = cost_m[h][w]
      visited = visited_m[h][w]
      kabe = S[h][w]
      if c_cost + 0 < tmp_cost and not visited and not kabe:
        cost_m[h][w] = c_cost + 0
        heapq.heappush(heap, (c_cost + 0, h, w))
        
  for h, w in enum_moveB(Ch, Cw):
    if 0 <= h <H and 0 <= w <W:
      tmp_cost = cost_m[h][w]
      visited = visited_m[h][w]
      kabe = S[h][w]
      if c_cost + 1 < tmp_cost and not visited and not kabe:
        cost_m[h][w] = c_cost + 1
        heapq.heappush(heap, (c_cost + 1, h, w))
    
total_cost = cost_m[Dh][Dw]
if total_cost < math.inf:
  print(total_cost)
else:
  print(-1)

### FIXED CODE ###

import heapq
import math
from collections import deque

H, W = map(int, input().split())
Ch, Cw = map(lambda x: int(x) - 1, input().split())
Dh, Dw = map(lambda x: int(x) - 1, input().split())

tobool = lambda s: s == "#"

S = [
  list(map(tobool, input())) for _ in range(H)
]
visited_m = [[False for w in range(W) ] for h in range(H)]
cost_m = [[math.inf for w in range(W) ] for h in range(H)]

def enum_moveA(Ch, Cw):
  return [(Ch-1, Cw), (Ch+1, Cw), (Ch, Cw-1), (Ch, Cw+1)]

def enum_moveB(Ch, Cw):
  return [
    (Ch-2, Cw-2), (Ch-2, Cw-1), (Ch-2, Cw), (Ch-2, Cw+1), (Ch-2, Cw+2),
    (Ch-1, Cw-2), (Ch-1, Cw-1), (Ch-1, Cw+1), (Ch-1, Cw+2),
    (Ch, Cw-2), (Ch, Cw+2),
    (Ch+1, Cw-2), (Ch+1, Cw-1), (Ch+1, Cw+1), (Ch+1, Cw+2),
    (Ch+2, Cw-2), (Ch+2, Cw-1), (Ch+2, Cw), (Ch+2, Cw+1), (Ch+2, Cw+2),
  ]

d = deque()
d.appendleft((0, Ch, Cw))
while True:
  if len(d) == 0:
    break
  visited_m[Ch][Cw] = True
  c_cost, Ch, Cw = d.popleft()
  if Ch == Dh and Cw == Dw:
    break
  for h, w in enum_moveA(Ch, Cw):
    if 0 <= h <H and 0 <= w <W:
      tmp_cost = cost_m[h][w]
      visited = visited_m[h][w]
      kabe = S[h][w]
      if c_cost + 0 < tmp_cost and not visited and not kabe:
        cost_m[h][w] = c_cost + 0
        d.appendleft((c_cost + 0, h, w))
        
  for h, w in enum_moveB(Ch, Cw):
    if 0 <= h <H and 0 <= w <W:
      tmp_cost = cost_m[h][w]
      visited = visited_m[h][w]
      kabe = S[h][w]
      if c_cost + 1 < tmp_cost and not visited and not kabe:
        cost_m[h][w] = c_cost + 1
        d.append((c_cost + 1, h, w))
    
total_cost = cost_m[Dh][Dw]
if total_cost < math.inf:
  print(total_cost)
else:
  print(-1)