Scanf.scanf "%d %d" (fun h w ->
    let s = Array.init h (fun _ -> Scanf.scanf " %s" (fun s -> s)) in

    let sentinel = max_int / 10 in
    let prev = Array.make_matrix h w (0, 0) in
    let d = Array.make_matrix h w sentinel in
    d.(0).(0) <- 0;

    let module S = Set.Make (struct type t = int * int let compare = compare end) in

    let rec loop set =
        if S.is_empty set then () else
            let ((y, x) as m) = S.min_elt set in
            let set = S.remove m set in
            let set = List.fold_left (fun set (vy, vx) ->
                let x0 = x + vx in
                let y0 = y + vy in
                if x0 >= 0 && x0 < w && y0 >= 0 && y0 < h && s.(y0).[x0] = '.' && d.(y0).(x0) > d.(y).(x) + 1 then (
                    d.(y0).(x0) <- d.(y).(x) + 1;
                    prev.(y0).(x0) <- (y, x);
                    S.add (y0, x0) set
                ) else set
            ) set [ -1, 0; 1, 0; 0, -1; 0, 1 ]
            in
            loop set
    in
    loop (S.singleton (0, 0));

    Printf.printf "%d\n" @@
    if d.(h - 1).(w - 1) = sentinel then -1 else (
        let rec loop y x set =
            if y = 0 && x = 0 then set else
                let ny, nx = prev.(y).(x) in
                let set = S.add (ny, nx) set in
                loop ny nx set
        in
        let set = loop (h - 1) (w - 1) (S.singleton (h - 1, w - 1)) in
        let rec loop_y y acc =
            let rec loop_x x acc =
                if x = w then loop_y (y + 1) acc else
                    let acc = if s.(y).[x] = '.' && not (S.mem (y, x) set) then acc + 1 else acc in
                    loop_x (x + 1) acc
            in
            if y = h then acc else loop_x 0 acc
        in
        loop_y 0 0
    )
)