Problem:
Score : 400 points

Problem Statement

A maze is composed of a grid of H \times W squares - H vertical, W horizontal.

The square at the i-th row from the top and the j-th column from the left - (i,j) - is a wall if S_{ij} is # and a road if S_{ij} is ..

There is a magician in (C_h,C_w). He can do the following two kinds of moves:

Move A: Walk to a road square that is vertically or horizontally adjacent to the square he is currently in.

Move B: Use magic to warp himself to a road square in the 5\times 5 area centered at the square he is currently in.

In either case, he cannot go out of the maze.

At least how many times does he need to use the magic to reach (D_h, D_w)?

Constraints

1 \leq H,W \leq 10^3

1 \leq C_h,D_h \leq H

1 \leq C_w,D_w \leq W

S_{ij} is # or ..

S_{C_h C_w} and S_{D_h D_w} are ..

(C_h,C_w) \neq (D_h,D_w)

Input

Input is given from Standard Input in the following format:

H W
C_h C_w
D_h D_w
S_{11}\ldots S_{1W}
\vdots
S_{H1}\ldots S_{HW}

Output

Print the minimum number of times the magician needs to use the magic. If he cannot reach (D_h,D_w), print -1 instead.

Sample Input 1

4 4
1 1
4 4
..#.
..#.
.#..
.#..

Sample Output 1

1

For example, by walking to (2,2) and then using the magic to travel to (4,4), just one use of magic is enough.

Note that he cannot walk diagonally.

Sample Input 2

4 4
1 4
4 1
.##.
####
####
.##.

Sample Output 2

-1

He cannot move from there.

Sample Input 3

4 4
2 2
3 3
....
....
....
....

Sample Output 3

0

No use of magic is needed.

Sample Input 4

4 5
1 2
2 5
#.###
####.
#..##
#..##

Sample Output 4

2

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)


// Problem : Wizard in Maze
// Contest : Virtual Judge - AtCoder
// URL : https://vjudge.net/problem/AtCoder-abc176_d
// Memory Limit : 1048 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")  // disable
using namespace std;
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define lll __int128;
using vi = vector<int>;
using vl = vector<ll>;
using pii = pair<int, int>;
using piii = pair<int, pair<int, int>>;
#define isin(mp, key) ((mp).find(key) != (mp).end())
#define pb push_back
#define fi first
#define se second
#define tos(x) string(1, x)
#define lp(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define vec(v, type, sz) vector<type> v(sz)
#define all(v) v.begin(), v.end()
#define MOD 1000000007
#define INF 2000000003
#define INFL 2000000000000000003ll
#define fast_io                       \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL);                    \
    cout.tie(NULL);
#define vii(v, n, m, val) vector<vector<int>> v(n, vector<int>(m, val))
#define viii(v, i, j, k, val)        \
    vector<vector<vector<int>>> v(i, \
                                  vector<vector<int>>(j, vector<int>(k, val)))
#define file_io                       \
    freopen("input.txt", "r", stdin); \
    freopen("output.txt", "w", stdout);
#define testc   \
    int tcc;    \
    cin >> tcc; \
    for (int tc = 1; tc <= tcc; tc++)
vector<string> vec_splitter(string s) {
    s += ',';
    vector<string> res;
    while (!s.empty()) {
        res.push_back(s.substr(0, s.find(',')));
        s = s.substr(s.find(',') + 1);
    }
    return res;
}
void debug_out(vector<string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
    cerr << endl;
}
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
    if (idx > 0)
        cerr << ", ";
    else
        cerr << "Line(" << LINE_NUM << ") ";
    stringstream ss;
    ss << H;
    cerr << args[idx] << " = " << ss.str();
    debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifdef DB
#define db(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define db(...) 42
#endif
#define rd_macro(_1, _2, _3, _4, NAME, ...) NAME
#define rd(...) rd_macro(__VA_ARGS__, rd4, rd3, rd2, rd1)(__VA_ARGS__)
#define rd1(x) \
    int x;     \
    cin >> x;
#define rd2(x, y) \
    int x, y;     \
    cin >> x >> y;
#define rd3(x, y, z) \
    int x, y, z;     \
    cin >> x >> y >> z;
#define rd4(w, x, y, z) \
    int w, x, y, z;     \
    cin >> w >> x >> y >> z;
template <typename... Args>
void pr(Args... args) {
    (std::cout << ... << args);
}
template <typename... Args>
void in(Args&&... args) {
    (std::cin >> ... >> args);
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); ++i) {
        os << v[i];
        if (i != (int)v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
    for (int i = 0; i < (int)v.size(); ++i) {
        is >> v[i];
    }
    return is;
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& v) {
    os << "[";
    for (auto it : v) {
        os << it;
        if (it != *v.rbegin()) os << ", ";
    }
    os << "]\n";
    return os;
}
template <typename T, typename S>
ostream& operator<<(ostream& os, const map<T, S>& v) {
    for (auto it : v) os << it.first << " : " << it.second << "\n";

    return os;
}
template <typename T, typename S>
ostream& operator<<(ostream& os, const pair<T, S>& v) {
    os << "(";
    os << v.first << ", " << v.second << ")";
    return os;
}
template <typename T, typename S>
istream& operator>>(istream& is, pair<T, S>& v) {
    is >> v.first >> v.second;
    return is;
}

int h, w, s1, s2, e1, e2;
vi dx = {0, 0, 1, -1};
vi dy = {1, -1, 0, 0};
vector<string> g;

inline bool ok(int nx, int ny) {
    return (nx >= 0 && nx < h && ny >= 0 && ny < w && g[nx][ny] == '.');
}

signed main() {
    fast_io;
    in(h, w, s1, s2, e1, e2);
    e1--, e2--, s1--, s2--;
    g.resize(h);
    in(g);
    db("1");
    vii(d, h, w, INFL);
    d[s1][s2] = 0;
    priority_queue<piii, vector<piii>, greater<piii>> q;
    q.push({0, {s1, s2}});
    while (!q.empty()) {
        auto [curd, u] = q.top();
        q.pop();
        if (d[u.fi][u.se] != curd) continue;
        lp(i, 0, 4) {
            int nx = u.fi + dx[i], ny = u.se + dy[i];
            if (ok(nx, ny) && d[u.fi][u.se] + 0 < d[nx][ny]) {
                d[nx][ny] = d[u.fi][u.se] + 0;
                q.push({d[nx][ny], {nx, ny}});
                db(u, pair(nx, ny));
            }
        }
        lp(tdx, -2, 3) {
            lp(tdy, -2, 3) {
                int nx = u.fi + tdx, ny = u.se + tdy;
                if (ok(nx, ny) && d[u.fi][u.se] + 1 < d[nx][ny]) {
                    d[nx][ny] = d[u.fi][u.se] + 1;
                    q.push({d[nx][ny], {nx, ny}});
                    db(nx, ny, d[nx][ny]);
                }
            }
        }
    }
    if (d[e1][e2] == INFL)
        pr("-1");
    else
        pr(d[e1][e2]);
}
// code!=think
// least efficient code to get ac