Problem:
Score : 400 points

Problem Statement

A maze is composed of a grid of H \times W squares - H vertical, W horizontal.

The square at the i-th row from the top and the j-th column from the left - (i,j) - is a wall if S_{ij} is # and a road if S_{ij} is ..

There is a magician in (C_h,C_w). He can do the following two kinds of moves:

Move A: Walk to a road square that is vertically or horizontally adjacent to the square he is currently in.

Move B: Use magic to warp himself to a road square in the 5\times 5 area centered at the square he is currently in.

In either case, he cannot go out of the maze.

At least how many times does he need to use the magic to reach (D_h, D_w)?

Constraints

1 \leq H,W \leq 10^3

1 \leq C_h,D_h \leq H

1 \leq C_w,D_w \leq W

S_{ij} is # or ..

S_{C_h C_w} and S_{D_h D_w} are ..

(C_h,C_w) \neq (D_h,D_w)

Input

Input is given from Standard Input in the following format:

H W
C_h C_w
D_h D_w
S_{11}\ldots S_{1W}
\vdots
S_{H1}\ldots S_{HW}

Output

Print the minimum number of times the magician needs to use the magic. If he cannot reach (D_h,D_w), print -1 instead.

Sample Input 1

4 4
1 1
4 4
..#.
..#.
.#..
.#..

Sample Output 1

1

For example, by walking to (2,2) and then using the magic to travel to (4,4), just one use of magic is enough.

Note that he cannot walk diagonally.

Sample Input 2

4 4
1 4
4 1
.##.
####
####
.##.

Sample Output 2

-1

He cannot move from there.

Sample Input 3

4 4
2 2
3 3
....
....
....
....

Sample Output 3

0

No use of magic is needed.

Sample Input 4

4 5
1 2
2 5
#.###
####.
#..##
#..##

Sample Output 4

2

Solution in OCaml (4.10.0) (judge verdict: Accepted)

module Weighted01DirectedGraph
  (* 頂点を添字，経路長を要素とした配列の実装 *)
  (Array : sig
    type t
    type key
    type elt = int (* 全ての重さが0か1なグラフなので経路長は非負整数 *)
    val get : t -> key -> elt
    val set : t -> key -> elt -> unit
  end)
: sig
  type vertex = Array.key

  val shortest_path :
    (* 全ての頂点についての経路長が無限大で初期化された配列 *)
    Array.t ->
    (* 最短経路を求めたいグラフの，ある頂点から伸びる辺に対してのイテレータ
       重みが0の辺に対してはf0を，1の辺に対してはf1を用いる *)
    (vertex -> f0:(vertex -> unit) -> f1:(vertex -> unit) -> unit) ->
    (* 始点 *)
    vertex ->
    (* 終点を受け取って，始点からの最短距離を返す関数
       始点から辿り着けない場合，無限大を返す
       この関数を覚えておけば，呼び出しごとの途中までの計算結果がシェアされる *)
    (vertex -> int)
end =
struct
  type vertex = Array.key

  let shortest_path d es s =
    (* 始点への経路長を0にする *)
    Array.set d s 0;
    let w = ref 1 in
    let q = ref [s] in
    let rec bfs t =
      match !q with
      (* もう既に全ての頂点までの経路が分かっているので返す *)
      | [] -> Array.get d t
      | us ->
          match Array.get d t with
          (* 既に終点までの距離が分かっているので返す *)
          | x when x < !w -> x
          (* 終点までの距離が分かっていないので，BFSを続行 *)
          | _ ->
              q := [];
              List.iter dfs us;
              incr w;
              bfs t
    and dfs u =
      es u
        ~f0:(fun v ->
          if !w <= Array.get d v then
            (Array.set d v (!w - 1); dfs v))
        ~f1:(fun v ->
          if !w < Array.get d v then
            (Array.set d v !w; q := v :: !q)) in
    bfs
end

module G = Weighted01DirectedGraph (struct
  type t = (int, Bigarray.int_elt, Bigarray.c_layout) Bigarray.Genarray.t
  type elt = int
  type key = int array
  let get = Bigarray.Genarray.get
  let set = Bigarray.Genarray.set
end)

let () = Scanf.scanf "%d %d\n%d %d\n%d %d\n" @@ fun h w ch cw dh dw ->
  let ss = Array.init h @@ fun _ -> Scanf.scanf "%s\n" @@ fun s -> s in
  let d =
    G.shortest_path
      (let d = Bigarray.Genarray.create Bigarray.int Bigarray.c_layout [| h; w |] in Bigarray.Genarray.fill d max_int; d)
      (fun [|i; j|] ~f0 ~f1 ->
        List.iter (fun (i', j') ->
          if 0 <= i' && i' < h && 0 <= j' && j' < w && ss.(i').[j'] = '.' then f0 [|i'; j'|])
        [(i - 1, j); (i + 1, j); (i, j - 1); (i, j + 1)];
        for i' = max 0 (i - 2) to min (h - 1) (i + 2) do
          for j' = max 0 (j - 2) to min (w - 1) (j + 2) do
            if ss.(i').[j'] = '.' then f1 [|i'; j'|]
          done
        done)
      [|ch - 1; cw - 1|]
      [|dh - 1; dw - 1|] in
  Printf.printf "%d\n" @@ if d = max_int then -1 else d