#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <utility>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <tuple>
#include <numeric>
#include <functional>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> P;
#define rep(i, n) for(ll i = 0; i < n; i++)
#define exrep(i, a, b) for(ll i = a; i <= b; i++)
#define out(x) cout << x << endl
#define exout(x) printf("%.10f\n", x)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define pb push_back
#define re0 return 0
const ll mod = 1000000007;
const ll INF = 1e16;

int main() {
    ll h, w;
    cin >> h >> w;

    ll sx, sy, gx, gy;
    cin >> sx >> sy >> gx >> gy;
    sx--;  sy--;  gx--;  gy--;

    vector<string> board(h);
    rep(i, h) {
        cin >> board[i];
    }
    
    vector<vector<P>> G(h*w);
    rep(i, h) {
        rep(j, w) {
            if(board[i][j] == '#') {
                continue;
            }
            ll v = w*i + j;
            if(0 < j && board[i][j-1] == '.') {
                G[v-1].pb(make_pair(v, 0));
                G[v].pb(make_pair(v-1, 0));
            }
            if(j < w-1 && board[i][j+1] == '.') {
                G[v+1].pb(make_pair(v, 0));
                G[v].pb(make_pair(v+1, 0));
            }
            if(0 < i && board[i-1][j] == '.') {
                G[v-w].pb(make_pair(v, 0));
                G[v].pb(make_pair(v-w, 0));
            }
            if(i < h-1 && board[i+1][j] == '.') {
                G[v+w].pb(make_pair(v, 0));
                G[v].pb(make_pair(v+w, 0));
            }
        }
    }

    rep(i, h) {
        rep(j, w) {
            if(board[i][j] == '#') {
                continue;
            }
            ll v = w*i + j;
            exrep(x, max(0LL, i-2), min(h-1, i+2)) {
                exrep(y, max(0LL, j-2), min(w-1, j+2)) {
                    if(board[x][y] == '#') {
                        continue;
                    }
                    if(x == i-1 && y == j) {
                        continue;
                    }
                    if(x == i && y == j-1) {
                        continue;
                    }
                    if(x == i && y == j) {
                        continue;
                    }
                    if(x == i && y == j+1) {
                        continue;
                    }
                    if(x == i+1 && y == j) {
                        continue;
                    }
                    ll u = w*x + y;
                    G[v].pb(make_pair(u, 1));
                    G[u].pb(make_pair(v, 1));
                }
            }
        }
    }

    ll sv = w*sx + sy;
    ll gv = w*gx + gy;

    // ダイクストラ法。計算量はO((V+E)*log(V))
    vl dp(h*w, INF);  // dp[v] : 頂点vへかかる時間の最小値
    dp[sv] = 0;
    priority_queue<P, vector<P>, greater<P>> prQ;
    prQ.push(make_pair(dp[sv], sv));  // (頂点vまでかかる時間t, いまいる頂点v)
    while(!prQ.empty()) {
        auto p1 = prQ.top();
        prQ.pop();
        ll t = p1.first;  // 頂点vまでかかる時間t
        ll v = p1.second;  // いまいる頂点v
        if(dp[v] < t) {
            continue;
        }
        for(auto p2 : G[v]) {
            ll u = p2.first;
            ll cost = p2.second;
            if(dp[u] > dp[v] + cost) {
                dp[u] = dp[v] + cost;
                prQ.push(make_pair(dp[u], u));
            }
        }
    }
    
    if(dp[gv] == INF) {
        out(-1);
    }
    else {
        out(dp[gv]);
    }
    
    re0;
}

Measured memory_bytes: 299632