#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <iostream>
#include <random>
#include <map>
#include <iomanip>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <cassert>
#include <fstream>
#include <unordered_map>
#include <cstdlib>
#include <complex>
#include <cctype>
#include <bitset>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
#define REP(i,n) for(ll i(0);(i)<(n);(i)++)
#define rep(i,n) for(ll i(0);(i)<(n);(i)++)
#define ALL(a) a.begin(), a.end()
#define enld endl //* missspell check
const ll INF = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }

vector<string> S;
ll H, W, N;
vll dx{0, 1, 0, -1}, dy{1, 0, -1, 0};
vll dx2{ 0,  0, 1,  1, 1,  1, 2, 2,  2, 2,  2, -1, -1, -1, -1, -2, -2, -2, -2, -2};
vll dy2{ 2, -2, 1, -1, 2, -2, 0, 1, -1, 2, -2,  1, -1,  2, -2,  0,  1, -1,  2, -2};
struct edge{
    ll to;
    ll cost;
    edge(ll t, ll c){
        to = t;
        cost = c;
    }
};
//* dijkstra algorithm with adjacency list
void dijkstra(vector<vector<edge> > &G, vll &dist, ll s){
    fill(dist.begin(), dist.end(), INF);
    priority_queue<pll, vector<pll>, greater<pll> > que;
    dist[s] = 0;
    que.push(pll(0, s));
    while(!que.empty()){
        ll score = que.top().first;
        ll u = que.top().second;
        que.pop();
        for(ll i=0; i< G[u].size(); i++){
            edge e = G[u][i];
            if(dist[e.to] > score + e.cost){
                dist[e.to] = score + e.cost;
                que.push(pll(dist[e.to], e.to));
            }
        }
    }
    return;
}

int main(){
    cin >> H >> W;
    N = H*W;
    ll Ch, Cw, Dh, Dw;
    cin >> Ch >> Cw >> Dh >> Dw;
    Ch--; Cw--; Dh--; Dw--;
    S.resize(H);
    REP(i, H){
        cin >> S[i];
    }
    vector<vector<edge> > G(N);
    REP(x, H){
        REP(y, W){
            if(S[x][y] == '#') continue;
            REP(k, 4){
                ll idx = x*W + y;
                ll xto = x + dx[k];
                ll yto = y + dy[k];
                if(0 <= xto && xto < H && 0 <= yto && yto < W && S[xto][yto]=='.'){
                    ll idxto = xto *W + yto;
                    G[idx].push_back(edge(idxto, 0LL));
                }
            }
            REP(k, 20){
                ll idx = x*W + y;
                ll xto = x + dx2[k];
                ll yto = y + dy2[k];
                if(0 <= xto && xto < H && 0 <= yto && yto < W && S[xto][yto] =='.'){
                    ll idxto = xto *W + yto;
                    G[idx].push_back(edge(idxto, 1LL));
                }
            }
        }
    }
    vll dist(N);
    dijkstra(G, dist, Ch*W+Cw);
    if(dist[Dh*W+Dw] >= INF) cout<<-1<<endl;
    else 
        cout << dist[Dh*W+Dw]<<endl;
    return 0;
}


Measured memory_bytes: 167548