h, w = gets.split(" ").map(&:to_i)
ch, cw = gets.split(" ").map(&:to_i)
dh, dw = gets.split(" ").map(&:to_i)

# indexの関係で-1する
caxs = [ch-1, cw-1] # 現在地
daxs = [dh-1, dw-1] # 目的地

arr = []
maze = h.times.map {
  arr << [] # 初期化処理をついでにやる
  gets.chomp
}

queue = [caxs]
queue2 = []

arr[ch-1][cw-1] = "0"
(h*w).times do |i|
  # 上下左右の移動
  while true
    x, y = queue.pop

    # ゴールなら終了
    if [x, y] == daxs
      puts i
      return
    end
    # 上下左右のマスを確認する
    [[-1, 0], [1, 0], [0, -1], [0, 1]].each do |dx, dy|
      nx = x + dx
      ny = y + dy
      # 座標範囲外または既に探査済みの場合スキップする
      next unless 0 <= nx && nx < h && 0 <= ny && ny < w && !arr[nx][ny]

      if maze[nx][ny] == "."
        arr[nx][ny] = i
        queue << [nx, ny]
      else
        arr[nx][ny] = -1
        queue2 << [nx, ny]
      end
    end

    # 斜め方向の2マス先のワープを検証するために斜めに壁があるか確認する
    [[-1, -1], [1, 1], [1, -1], [-1, 1]].each do |dx, dy|
      nx = x + dx
      ny = y + dy
      # 座標範囲外または既に探査済みの場合スキップする
      next unless 0 <= nx && nx < h && 0 <= ny && ny < w && (!arr[nx][ny] || arr[nx][ny] != -2)

      if maze[nx][ny] == "#"
        arr[nx][ny] = -1
        queue2 << [nx, ny]
      end
    end

    break if queue.length == 0
  end
  break if queue.length == 0 && queue2.length == 0

  # ワープ
  while true
    x, y = queue2.pop

    [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, 1], [1, -1], [-1, -1], [1, 1]].each do |dx, dy|
      nx = x + dx
      ny = y + dy
      # 座標範囲外または既に探査済みの場合スキップする
      next unless 0 <= nx && nx < h && 0 <= ny && ny < w && !arr[nx][ny]

      if maze[nx][ny] == "."
        arr[nx][ny] = i+1
        queue << [nx, ny]
      else
        arr[nx][ny] = -2
      end
    end

    break if queue2.length == 0
  end
  
  break if queue.length == 0 && queue2.length == 0
end
p -1
