use proconio::marker::{Chars, Usize1};
use proconio::{fastout, input};

#[allow(unused_macros)]
macro_rules! multi_vec {
    ( $elem:expr; $num:expr ) => (vec![$elem; $num]);
    ( $elem:expr; $num:expr, $($rest:expr),* ) => (vec![multi_vec![$elem; $($rest),*]; $num]);
}

const WALL: char = '#';
const ROAD: char = '.';
const INF: usize = std::usize::MAX >> 2;
#[fastout]
fn main() {
    input! {
        h: usize,
        w: usize,
        c: (Usize1, Usize1),
        d: (Usize1, Usize1),
        s: [Chars; h],
    }

    let colors = multi_vec![-1i64; h, w];
    let visited = multi_vec![false; h, w];
    let mut solve = Solve {
        h,
        w,
        c,
        d,
        s,
        colors,
        visited,
    };
    solve.solve();
}

struct Solve {
    h: usize,
    w: usize,
    c: (usize, usize),
    d: (usize, usize),
    s: Vec<Vec<char>>,
    colors: Vec<Vec<i64>>,
    visited: Vec<Vec<bool>>,
}

impl Solve {
    fn solve(&mut self) {
        let h = self.h;
        let w = self.w;
        let mut color = 0;
        for i in 0..h {
            for j in 0..w {
                let result = self.dfs((i, j), color);
                if result {
                    color += 1;
                }
            }
        }

        let distances = self.dijkstra(self.c);
        let d = self.d;
        let ans = distances[d.0][d.1];
        let ans: i64 = if ans == INF { -1 } else { ans as i64 };
        println!("{}", ans);
    }

    fn dfs(&mut self, now: (usize, usize), color: i64) -> bool {
        if self.colors[now.0][now.1] != -1 || self.s[now.0][now.1] == WALL {
            return false;
        }

        self.colors[now.0][now.1] = color;
        let (now1, now2) = now;
        if now1 + 1 < self.h && self.colors[now1 + 1][now2] == -1 && self.s[now1 + 1][now2] == ROAD
        {
            self.dfs((now1 + 1, now2), color);
        }
        if now1 >= 1 && self.colors[now1 - 1][now2] == -1 && self.s[now1 - 1][now2] == ROAD {
            self.dfs((now1 - 1, now2), color);
        }
        if now2 + 1 < self.w && self.colors[now1][now2 + 1] == -1 && self.s[now1][now2 + 1] == ROAD
        {
            self.dfs((now1, now2 + 1), color);
        }
        if now2 >= 1 && self.colors[now1][now2 - 1] == -1 && self.s[now1][now2 - 1] == ROAD {
            self.dfs((now1, now2 - 1), color);
        }

        true
    }

    fn dijkstra(&mut self, (s1, s2): (usize, usize)) -> Vec<Vec<usize>> {
        use std::cmp::Reverse;
        use std::collections::BinaryHeap;

        let h = self.h;
        let w = self.w;

        let mut distances = multi_vec![INF; h, w];
        distances[s1][s2] = 0;

        // BinaryHeapは最大ヒープなので、Reverseで距離最小のものを取り出せるようにする
        // ヒープの中身は Reverse((distance, distination))
        let mut queue: BinaryHeap<Reverse<(usize, (usize, usize))>> = BinaryHeap::new();
        queue.push(Reverse((0, (s1, s2))));

        while !queue.is_empty() {
            let Reverse((d, (u1, u2))) = queue.pop().unwrap();
            let alt = d;
            for (i, j) in vec![(1, 0), (-1, 0), (0, 1), (0, -1)] {
                let u1 = u1 as i64;
                let u2 = u2 as i64;
                if 0 <= u1 + i
                    && u1 + i < h as i64
                    && 0 <= u2 + j
                    && u2 + j < w as i64
                    && self.s[(u1 + i) as usize][(u2 + j) as usize] == ROAD
                    && distances[(u1 + i) as usize][(u2 + j) as usize] > alt
                {
                    distances[(u1 + i) as usize][(u2 + j) as usize] = alt;
                    queue.push(Reverse((alt, ((u1 + i) as usize, (u2 + j) as usize))));
                }
            }

            let alt = d + 1;
            for i in -2..=2 {
                for j in -2..=2 {
                    let u1 = u1 as i64;
                    let u2 = u2 as i64;
                    if 0 <= u1 + i
                        && u1 + i < h as i64
                        && 0 <= u2 + j
                        && u2 + j < w as i64
                        && self.s[(u1 + i) as usize][(u2 + j) as usize] == ROAD
                        && distances[(u1 + i) as usize][(u2 + j) as usize] > alt
                    {
                        distances[(u1 + i) as usize][(u2 + j) as usize] = alt;
                        queue.push(Reverse((alt, ((u1 + i) as usize, (u2 + j) as usize))));
                    }
                }
            }
        }

        distances
    }
}


Measured memory_bytes: 23988