use std::cmp::Reverse;

/// input macro from https://qiita.com/tanakh/items/1ba42c7ca36cd29d0ac8
macro_rules ! read_value {($ next : expr , ($ ($ t : tt ) ,* ) ) => {($ (read_value ! ($ next , $ t ) ) ,* ) } ; ($ next : expr , [$ t : tt ; $ len : expr ] ) => {(0 ..$ len ) . map (| _ | read_value ! ($ next , $ t ) ) . collect ::< Vec < _ >> () } ; ($ next : expr , chars ) => {read_value ! ($ next , String ) . chars () . collect ::< Vec < char >> () } ; ($ next : expr , usize1 ) => {read_value ! ($ next , usize ) - 1 } ; ($ next : expr , $ t : ty ) => {$ next () . parse ::<$ t > () . expect ("Parse error" ) } ; }
macro_rules ! input_inner {($ next : expr ) => {} ; ($ next : expr , ) => {} ; ($ next : expr , $ var : ident : $ t : tt $ ($ r : tt ) * ) => {let $ var = read_value ! ($ next , $ t ) ; input_inner ! {$ next $ ($ r ) * } } ; }
macro_rules ! input {(source = $ s : expr , $ ($ r : tt ) * ) => {let mut iter = $ s . split_whitespace () ; let mut next = || {iter . next () . unwrap () } ; input_inner ! {next , $ ($ r ) * } } ; ($ ($ r : tt ) * ) => {let stdin = std :: io :: stdin () ; let mut bytes = std :: io :: Read :: bytes (std :: io :: BufReader :: new (stdin . lock () ) ) ; let mut next = move || -> String {bytes . by_ref () . map (| r | r . unwrap () as char ) . skip_while (| c | c . is_whitespace () ) . take_while (| c |! c . is_whitespace () ) . collect () } ; input_inner ! {next , $ ($ r ) * } } ; }

fn solve() {
    input! {
        h: usize,
        w: usize,
        c : (usize1,usize1),
        d: (usize1,usize1),
        s: [chars;h]
    };

    let mut warp_count = vec![vec![std::usize::MAX; w]; h];
    let mut arrived = vec![vec![false; w]; h];

    let mut dequeue = std::collections::BinaryHeap::new();
    dequeue.push((Reverse(0), c.0, c.1));

    while !dequeue.is_empty() {
        let (Reverse(c), x, y) = dequeue.pop().unwrap();

        if !arrived[x][y] {
            warp_count[x][y] = warp_count[x][y].min(c);
            arrived[x][y] = true;

            for i in 0..5 {
                for j in 0..5 {
                    if ((x + i) >= 2) && ((x + i) < h + 2) && ((y + j) >= 2) && ((y + j) < w + 2) {
                        let next_x = x + i - 2;
                        let next_y = y + j - 2;

                        if (s[next_x][next_y] == '.') && !arrived[next_x][next_y] {
                            let dist_x = next_x.max(x) - next_x.min(x);
                            let dist_y = next_y.max(y) - next_y.min(y);

                            if (dist_x == 0 && dist_y == 1) || (dist_x == 1 && dist_y == 0) {
                                dequeue.push((Reverse(c), next_x, next_y));
                            }
                            else {
                                dequeue.push((Reverse(c + 1), next_x, next_y));
                            }
                        }
                    }
                }
            }
        }
    }

    if warp_count[d.0][d.1] == std::usize::MAX {
        println!("-1");
    }
    else {
        println!("{}", warp_count[d.0][d.1]);
    }
}

fn main() {
    std::thread::Builder::new()
        .name("solve".into())
        .stack_size(256 * 1024 * 1024)
        .spawn(solve)
        .unwrap()
        .join()
        .unwrap();
}


Measured memory_bytes: 15380