#![allow( dead_code, non_snake_case, unused_imports, unused_mut, unused_variables, while_true, unused_assignments, clippy::needless_range_loop, clippy::ptr_arg, clippy::type_complexity, clippy::unnecessary_cast )] use proconio::{ input, marker::{Chars, Usize1 as usize1}, source::line::LineSource, }; use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque}; use std::io::{BufReader, Write, stdin, stdout}; use std::mem::{swap, take}; macro_rules! mat { ($elem:expr; $n:expr) => { vec![$elem; $n] }; ($elem:expr; $dim0:expr; $($dim:expr);*) => { vec![mat![$elem; $($dim);*]; $dim0] }; } const D4X: [isize; 4] = [-1, 0, 1, 0]; const D4Y: [isize; 4] = [0, 1, 0, -1]; fn is_prime(n: usize) -> bool { if n < 2 { return false; } for i in 2..=((n as f64).sqrt() as usize) { if n % i == 0 { return false; } } true } fn find_best(mut a: usize, mut b: usize) -> Option { let k = a.abs_diff(b); if k % 2 == 1 { let m = a.min(b); let u = 2_usize.saturating_sub(m); a += u; b += u; if !is_prime(a) || !is_prime(b) { return None; } return Some(u); } let mut u = 0; while !is_prime(a) || !is_prime(b) { a += 1; b += 1; u += 1; } Some(u) } fn main() { input! { H: usize, W: usize, mut Sx: usize1, mut Sy: usize1, mut Gx: usize1, mut Gy: usize1, mut C: [Chars; H], }; if Sy > Gy { Sy = W - 1 - Sy; Gy = W - 1 - Gy; for i in 0..H { C[i].reverse(); } } if Sx > Gx { Sx = H - 1 - Sx; Gx = H - 1 - Gx; C.reverse(); } // 01BFS let inf = (H * W).pow(2); let mut dist = mat![inf; H; W; H * W + 1]; let mut que = VecDeque::new(); que.push_front((Sx, Sy, 0, 0)); dist[Sx][Sy][0] = 0; while let Some((x, y, use_down, c)) = que.pop_front() { if dist[x][y][use_down] < c { continue; } if x == Gx && y == Gy { continue; } for dir in 0..4 { let nx = x as isize + D4X[dir]; let ny = y as isize + D4Y[dir]; if nx < 0 || nx >= H as isize || ny < 0 || ny >= W as isize { continue; } let nx = nx as usize; let ny = ny as usize; if C[nx][ny] == '#' { continue; } let c_down = if D4Y[dir] == 1 { 1 } else { 0 }; let c_right = if D4X[dir] == 1 { 1 } else { 0 }; let use_down = use_down + c_down; if use_down > H * W { continue; } let nc = c + c_right; if dist[nx][ny][use_down] > nc { dist[nx][ny][use_down] = nc; if c_right == 0 { que.push_front((nx, ny, use_down, nc)); } else { que.push_back((nx, ny, use_down, nc)); } } } } let mut ans = inf; for u_d in 0..=H * W { let u_r = dist[Gx][Gy][u_d]; if u_r == inf { continue; } if u_r < (Gy - Sy) { continue; } if u_d < (Gx - Sx) { continue; } let u_l = u_r - (Gy - Sy); let u_u = u_d - (Gx - Sx); let mut cur = u_d + u_r + u_l + u_u; // if u_d == 5 { // dbg!(cur); // dbg!((u_d, u_u, u_r, u_l)); // dbg!(find_best(0, 2)); // } match find_best(u_d, u_u) { Some(u) => { if u > 0 && u_d == 0 && u_u == 0 { continue; } cur += u * 2; } None => { continue; } } match find_best(u_r, u_l) { Some(u) => { if u > 0 && u_l == 0 && u_r == 0 { continue; } cur += u * 2; } None => { continue; } } ans = ans.min(cur); } if ans == inf { println!("-1"); } else { println!("{}", ans); } }