#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using P = pair<ll,ll>;
using um = unordered_map<ll,ll>;
#define fl cout<<flush;
#define endl '\n'
template <typename T> inline void prt(T v){cout<<v<<'\n';}
template <typename T> inline bool chmax(T &a, const T &b){if (a<b){a=b;return 1;}return 0;}
template <typename T> inline bool chmin(T &a, const T &b){if (a>b){a=b;return 1;}return 0;}
const ll INF=1LL<<59;
const ll MOD=(ll)1e9+7;
const ll MOD2=998244353;
const ld pi=3.14159265358979323846;
const ld eps=1e-10;

ll H,W;
vector<vector<char>> S(1000, vector<char>(1000,' '));
vector<vector<ll>> num(1000, vector<ll>(1000,-1));

inline void dfs1(ll h,ll w,ll k){
    num[h][w]=k;
    if(h>0&&S[h-1][w]=='.'&&num[h-1][w]==-1)dfs1(h-1,w,k);
    if(h<H-1&&S[h+1][w]=='.'&&num[h+1][w]==-1)dfs1(h+1,w,k);
    if(w>0&&S[h][w-1]=='.'&&num[h][w-1]==-1)dfs1(h,w-1,k);
    if(w<W-1&&S[h][w+1]=='.'&&num[h][w+1]==-1)dfs1(h,w+1,k);
}
#define debug(v) cout<<#v<<": ",prt(v);
template <typename A,typename B>
inline void prt(pair<A,B> p){cout<<"("<<p.first<<", "<<p.second<<")\n";}
template <typename A,typename B,typename C>
inline void prt(tuple<A,B,C> p){cout<<"("<<get<0>(p)<<", "<<get<1>(p)<<", "<<get<2>(p)<<")\n";}
inline void prt(bool p){if(p)cout<<"True"<<'\n';else cout<<"False"<<'\n';}
template <typename T> 
inline void prt(vector<T> v){cout<<'{';for(ll i=0;i<v.size();i++){cout<<v[i];if(i<v.size()-1)cout<<", ";}cout<<'}'<<'\n';}
template <typename T> 
inline void prt(deque<T> v){cout<<'{';for(ll i=0;i<v.size();i++){cout<<v[i];if(i<v.size()-1)cout<<", ";}cout<<'}'<<'\n';}
template <typename A,typename B>
inline void prt(map<A,B> v){cout<<'{';ll c=0;for(auto &p: v){cout<<p.first<<":"<<p.second;c++;if(c!=v.size())cout<<", ";}cout<<'}'<<'\n';}
template <typename A,typename B>
inline void prt(unordered_map<A,B> v){cout<<'{';ll c=0;for(auto &p: v){cout<<p.first<<":"<<p.second;c++;if(c!=v.size())cout<<", ";}cout<<'}'<<'\n';}
template <typename T> 
inline void prt(set<T> v){cout<<'{';for(auto i=v.begin();i!=v.end();i++){cout<<*i;if(i!=--v.end())cout<<", ";}cout<<'}'<<'\n';}
template <typename T> 
inline void prt(multiset<T> v){cout<<'{';for(auto i=v.begin();i!=v.end();i++){cout<<*i;if(i!=--v.end())cout<<", ";}cout<<'}'<<'\n';}
signed main(void){
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);
    //ll H;
    cin >> H;
    //ll W;
    cin >> W;
    ll a;
    cin >> a;
    ll b;
    cin >> b;
    ll c;
    cin >> c;
    ll d2;
    cin >> d2;
    a--;b--;c--;d2--;
    for(ll i=0;i<H;++i)
        for(ll j=0;j<W;++j)cin>>S[i][j];
    dfs1(a,b,0);
    ll pp=1;
    for(ll i=0;i<H;++i)
        for(ll j=0;j<W;++j){
            if(S[i][j]=='.'&&num[i][j]==-1)
            dfs1(i,j,pp);
            pp++;
        }
    ll goal=num[c][d2];
    vector<vector<P>> G(H*W+1, vector<P>(0));
    for(ll i=0;i<H;++i)
        for(ll j=0;j<W;++j){
            if(S[i][j]=='#'||num[i][j]==-1)continue;
            for(ll k=-2;k<=2;++k){
                for(ll l=-2;l<=2;++l){
                    if(!(i+k>=0&&i+k<H&&j+l>=0&&j+l<W&&S[i+k][j+l]=='.'))continue;
                    if(num[i][j]!=num[i+k][j+l]&&num[i+k][j+l]!=-1)
                    G[num[i][j]].emplace_back(P(num[i+k][j+l],1));
                }
            }
        }
    
    //ダイクストラ法
    //vvl GにP(to,cost)って感じで隣接リストにしておく
    //計算量|E|log|V|
    //頂点数N
    priority_queue<P, vector<P>, greater<P>> pq;
    vector<ll> d(H*W+1,INF);
    d[0]=0;
    pq.emplace(P(0,0));
    while(!pq.empty()){
        P x=pq.top();
        pq.pop();
        ll &y=x.first;
        ll &z=x.second;
        if(y>d[z])continue;
        for(auto p: G[z]){
            if(d[p.first]>d[z]+p.second){
                d[p.first]=d[z]+p.second;
                pq.emplace(P(d[p.first],p.first));
            }
        }
    }
    if(d[goal]==INF){
        prt(-1);
        return 0;
    }

    prt(d[goal]);
    

    return 0;
}



Measured memory_bytes: 86332