require "set"

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]
arr[ch-1][cw-1] = 0
(h*w).times do |i|
  queue2 = Set.new
  queue3 = Set.new
  # 上下左右の移動
  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
      
      # いったんすべて格納する
      queue3 << [nx, ny]
      arr[nx][ny] = -1 if maze[nx][ny] == "#"
    end

    break if queue.length == 0
  end
  
  queue3.each do |x, y|
    queue2 << [x, y] if arr[x][y].nil? || arr[x][y] == -1
  end
  break if queue.length == 0 && queue2.length == 0

  tmp_queue = queue2.to_a
  # ワープ
  while true
    x, y = tmp_queue.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 tmp_queue.length == 0
  end
  
  break if queue.length == 0
end
 arr.each {|a| p a }
p -1
