// ゴミ

let inputNums () =
    stdin.ReadLine().Split() |> Array.map int

let sizeH, sizeW =
    inputNums ()
    |> fun a -> a.[0], a.[1]

printfn "sizeH, sizeW: %A" (sizeH, sizeW)

let startH, startW =
    inputNums ()
    |> fun a -> a.[0] - 1, a.[1] - 1

printfn "startH, startW: %A" (startH, startW)

let goalH, goalW =
    inputNums ()
    |> fun a -> a.[0] - 1, a.[1] - 1

printfn "goalH, goalW: %A" (goalH, goalW)

let grid =
    array2D [ for _ in 1 .. sizeH -> stdin.ReadLine().ToCharArray() ]

printfn "grid:\n%A" grid

let isOnRoad (h, w, m) =
    // printfn
    //     "isOnRoad %A : %A"
    //     (h, w, m)
    //     ((h >= 0)
    //      && (h < sizeH)
    //      && (w >= 0)
    //      && (w < sizeW)
    //      && grid.[h, w] <> '#')

    (h >= 0)
    && (h < sizeH)
    && (w >= 0)
    && (w < sizeW)
    && grid.[h, w] <> '#'

let isNewPlace (path: list<int * int>) (h, w, m) =
    // printfn "isNewPlace %A: %A" (h, w, m) (not (Seq.contains (h, w) path))
    not (Seq.contains (h, w) path)

let moveA (h, w, m) =
    // printfn
    //     "moveA list: %A"
    //     (seq {
    //         h - 1, w, m
    //         h, w + 1, m
    //         h + 1, w, m
    //         h, w + 1, m
    //      })

    seq {
        h - 1, w, m
        h, w + 1, m
        h + 1, w, m
        h, w + 1, m
    }

let moveB (h, w, m) =
    // printfn
    //     "moveB list: %A"
    //     (seq {
    //         for ih in h - 2 .. h + 2 do
    //             for iw in w - 2 .. w + 2 do
    //                 (ih, iw, m + 1)
    //      })

    seq {
        for ih in h - 2 .. h + 2 do
            for iw in w - 2 .. w + 2 do
                (ih, iw, m + 1)
    }

let move (path: list<int * int>) (h, w, m) =
    let placesA = moveA (h, w, m)

    let placesB =
        moveB (h, w, m)
        |> Seq.except (placesA |> Seq.map (fun (h, w, m) -> h, w, m + 1))

    printfn
        "FinalMovable: %A"
        (Seq.append placesA placesB
         |> Seq.filter isOnRoad
         |> Seq.filter (isNewPlace path)
         |> Seq.distinct)


    Seq.append placesA placesB
    |> Seq.filter isOnRoad
    |> Seq.filter (isNewPlace path)
    |> Seq.distinct

let rec solve path minMagic (h, w, m) =
    let updatedPath = (h, w) :: path

    printfn "Now: %A (ReversedPath: %A)" (h, w, m) path

    if h = goalH && w = goalW then
        printfn
            "minMagic: %A"
            (match minMagic with
             | -1 -> m
             | num -> min num m)

        match minMagic with
        | -1 -> m
        | num -> min num m
    else
        let nextSeq = move updatedPath (h, w, m)
        match Seq.isEmpty nextSeq with
        | true -> -1
        | false ->
            nextSeq
            |> Seq.map (solve updatedPath minMagic)
            |> Seq.except [| -1 |]
            |> fun sq ->
                printfn "minMagics: %A\n" sq
                Seq.min sq

solve [] -1 (startH, startW, 0) |> printfn "%d"
