// -*- coding:utf-8-unix -*-

use proconio::input;
use std::collections::VecDeque;

fn map2d<InnerIt: IntoIterator, It: Iterator<Item = InnerIt>, B>(
    it: It,
    f: fn(InnerIt::Item) -> B,
) -> Vec<Vec<B>> {
    it.map(|row| row.into_iter().map(f).collect::<Vec<_>>())
        .collect::<Vec<_>>()
}

#[allow(non_snake_case)]
fn main() {
    input! {
        Y: usize,
        X: usize,
        _sy: usize,
        _sx: usize,
        _gy: usize,
        _gx: usize,
        _S: [String; Y],
    }
    let dir = [1i64, 0, -1, 0, 1];
    let sy = _sy - 1;
    let sx = _sx - 1;
    let gy = _gy - 1;
    let gx = _gx - 1;
    let map = map2d(_S.iter().map(|row| row.chars()), |ch| ch == '.');
    let validate = |x, y| {
        if 0 <= x && x < X as i64 && 0 <= y && y < Y as i64 && map[y as usize][x as usize] {
            Some((x as usize, y as usize))
        } else {
            None
        }
    };
    // assign a unique id to each connected component
    let mut id_map = vec![vec![None; X]; Y];
    // islands[id]: all points in the id-th connected component
    let mut islands = Vec::new();
    let mut queue = VecDeque::new();
    for y in 0..Y {
        for x in 0..X {
            if !map[y][x] {
                continue;
            }
            if let Some(_) = id_map[y][x] {
                continue;
            }
            let id = islands.len() as i32;
            let mut island = Vec::new();
            queue.push_back((x, y));
            while let Some((x, y)) = queue.pop_front() {
                if let Some(_) = id_map[y][x] {
                    continue;
                }
                id_map[y][x] = Some(id);
                island.push((x, y));
                for i in 0..4 {
                    let x = x as i64 + dir[i];
                    let y = y as i64 + dir[i + 1];
                    if let Some((x, y)) = validate(x, y) {
                        queue.push_back((x, y));
                    }
                }
            }
            islands.push(island);
        }
    }
    let id_map = id_map;
    let s_id = id_map[sy][sx].unwrap() as usize;
    let g_id = id_map[gy][gx].unwrap() as usize;
    // calculate distance from s_id
    let mut queue = VecDeque::new();
    let mut distance = vec![None; islands.len()];
    queue.push_back((s_id as usize, 0));
    while let Some((id, d)) = queue.pop_front() {
        if distance[id].map(|_d| d < _d).unwrap_or(true) {
            distance[id] = Some(d);
            if id == g_id {
                break;
            }
            for (x, y) in &islands[id] {
                let (x, y) = (*x as i64, *y as i64);
                for dx in -2..=2 {
                    for dy in -2..=2 {
                        let x = x + dx;
                        let y = y + dy;
                        if let Some((x, y)) = validate(x, y) {
                            let next_id = id_map[y][x].unwrap() as usize;
                            if next_id != id {
                                queue.push_back((next_id, d + 1));
                            }
                        }
                    }
                }
            }
        }
    }
    println!("{}", distance[g_id].unwrap_or(-1));
}


Measured memory_bytes: 27504