DEBUG = 0

INF = 10**9
WALK = [[0, 1], [0, -1], [1, 0], [-1, 0]]
WARP = [*[-2, -1, 1, 2].product([-2, -1, 1, 2]), [2, 0], [-2, 0], [0, 2], [0, -2]]

h, w = gets.split.map &:to_i
ch, cw = gets.split.map &:to_i
dh, dw = gets.split.map &:to_i
# 番兵をつけておく
v_margin = [[-1] * (w + 4)] * 2
dists = v_margin + h.times.map { [-1, -1] + gets.chomp.each_char.map { _1 == '.' ? INF : -2 } + [-1, -1] } + v_margin

puts maze if DEBUG >= 1

# 01-BFS
start = [ch - 1 + 2, cw - 1 + 2, 0]
goal_x, goal_y = dh - 1 + 2, dw - 1 + 2
dists[start[0]][start[1]] = 0
queue = [start]
until queue.empty?
  p queue if DEBUG >= 1
  puts maze if DEBUG >= 2
  i, j, cost = *queue.shift
  
  # ゴールなら
  if i == goal_x and j == goal_y
    p cost
    exit
  end

  is_edge = false
  WALK.each do |(di, dj)|
    _i, _j = i + di, j + dj
    if dists[_i][_j] <= cost
      # 枝刈り1用
      is_edge = true if dists[_i][_j] == -2

      next
    end
    dists[_i][_j] = cost
    queue.unshift [_i, _j, cost]
  end

  # 枝刈り1: 徒歩範囲の内部ではワープしない
  if is_edge
    WARP.each do |(di, dj)|
      _i, _j, _cost = i + di, j + dj, cost + 1

      # 枝刈り2: 更新できないときはキューに追加しない
      next if _cost >= dists[_i][_j]

      dists[_i][_j] = _cost
      queue << [_i, _j, _cost]
    end
  end
end

# 到達できない場合
p -1
