let ( @! ) = List.nth let ( @> ) arr (i ,j) = arr.(i - 1).(j - 1) let choose f lst = let rec choose' f lst result = match lst with | [] -> result | x::xs -> let nextResult = match f x with | Some v -> v::result | None -> result in choose' f xs nextResult in choose' f lst [] let searchPath mapArr (w, h) (sy, sx) (gy, gx) = let chkArr = Array.make_matrix w h false and dxy = [(1, 0); (0, 1); (-1, 0); (0, -1)] in let canMove1 (cy, cx) (dy, dx) = let y, x = cy + dy, cx + dx in if y >= 1 && y <= w && x >= 1 && x <= h && abs((mapArr @> (y, x)) - (mapArr @> (cy, cx))) <= 1 && not (chkArr @> (y, x)) then Some (y, x) else None and canMove2 (cy, cx) (dy, dx) = let y1, y2 = cy + dy, cy + dy * 2 and x1, x2 = cx + dx, cx + dx * 2 in if y2 >= 1 && y2 <= w && x2 >= 1 && x2 <= h && mapArr @> (cy, cx) = mapArr @> (y2, x2) && mapArr @> (cy, cx) > mapArr @> (y1, x1) && not (chkArr @> (y2, x2)) then Some (y2, x2) else None in let rec searchPath' lst = match lst with | [] -> false | pos::rest -> let cy, cx = pos in if cy = gy && cx = gx then true else ( let cand1 = choose (canMove1 (cy, cx)) dxy and cand2 = choose (canMove2 (cy, cx)) dxy in let candLst = cand1 @ cand2 in let nextLst = candLst @ rest in List.iter (fun (y, x) -> chkArr.(y - 1).(x - 1) <- true) candLst; searchPath' nextLst ) in searchPath' [(sy, sx)] let () = let h, w = read_line () |> Str.split (Str.regexp_string " ") |> fun lst -> (int_of_string (lst @! 0), int_of_string (lst @! 1)) and sx, sy, gx, gy = read_line () |> Str.split (Str.regexp_string " ") |> fun lst -> (int_of_string (lst @! 0), int_of_string (lst @! 1), int_of_string (lst @! 2), int_of_string (lst @! 3)) in let mapArr = Array.make_matrix w h 0 in let rec readB x = if x < h then ( let line = read_line () in String.iteri (fun y c -> mapArr.(y).(x) <- int_of_char c - int_of_char '0') line; readB (x + 1) ) in readB 0; searchPath mapArr (w, h) (sy, sx) (gy, gx) |> (function | true -> "YES" | false -> "NO") |> print_endline