#include <bits/stdc++.h>
#include <map>
#include <algorithm> 
#include <vector> 
#include <string.h> 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <chrono> 
#include <thread> 
#include <iomanip>
#include <typeinfo>
 
//define
#define trav(i,v)   for(auto i: v)
#define rep(i,n)    for(int i=0;i<n;i++)
#define repu(i,k,n) for(int i=k;i<=n;i++)
#define repd(i,k,n) for(int i=k;i>=n;i--)
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define all(v)  v.begin(), v.end()
#define itn int 

//typedef
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef std::pair<int, int> pii;
typedef std::vector<int> vi;
typedef std::vector< pii > vii;
typedef std::vector< ll > vll;
typedef std::vector< std::pair < pii, int > > vpp;
 
const long long MOD = 1000000007;
// const long long MOD = 998244353;
const long long inf = 1000000000000000000;

using namespace std;

ll modpow(ll x,ll n){
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%MOD;
        x=x*x%MOD;
        n>>=1;
    }
    return res;
}

ll power(ll x, ll n)
{
    ll res=1;
    while(n>0){
        if(n&1) res=res*x;
        x=x*x;
        n>>=1;
    }
    return res;
}

void update(int n, vi &v, int x, int ch)
{
    while(x<=n)
    {
        v[x]+=ch;
        x+=(x&(-x));
    }
}

int query(vi &v, int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=v[x];
        x-=(x&(-x));
    }
    return ans;
}

void solve()
{
    int n, m;
    cin>>n>>m;
    int x1, y1, x2, y2;
    cin>>x1>>y1;
    cin>>x2>>y2;
    string s[n+1];
    repu(i,1,n)
    {
        cin>>s[i];
        s[i]='.'+s[i];
    }
    int vis[n+1][m+1];
    repu(i,1,n)
        repu(j,1,m)
            vis[i][j]=0;
    ll v[n+1][m+1];
    repu(i,1,n)
        repu(j,1,m)
            v[i][j]=0;
    multiset<pair<ll, pii>> q;
    q.insert(mp(0LL,mp(x1,y1)));
    while(!q.empty() && vis[x2][y2]==0)
    {
        if(vis[x2][y2])
            break;
        pair<ll, pii> p=(*q.begin());
        q.erase(q.begin());
        int x=p.se.fi, y=p.se.se;
        ll z=p.fi;
        if(vis[x][y]==1)
            continue;
        v[x][y]=p.fi;
        vis[x][y]=1;
        if(x==x2 && y==y2)
        {
            break;
        }
        if(x+1<=n && vis[x+1][y]==0 && s[x+1][y]=='.')
        {
            q.insert(mp(z,mp(x+1,y)));
        }
        if(y+1<=m && vis[x][y+1]==0 && s[x][y+1]=='.')
        {
            q.insert(mp(z,mp(x,y+1)));
        }
        if(x-1>=1 && vis[x-1][y]==0 && s[x-1][y]=='.')
        {
            q.insert(mp(z,mp(x-1,y)));
        }
        if(y-1>=1 && vis[x][y-1]==0 && s[x][y-1]=='.')
        {
            q.insert(mp(z,mp(x,y-1)));
        }
        repu(xx,x-2,x+2)
        {
            repu(yy,y-2,y+2)
            {
                if(xx>=1 && xx<=n && yy>=1 && yy<=m && vis[xx][yy]==0 && s[xx][yy]=='.')
                    q.insert(mp(z+1ll,mp(xx,yy)));
            }
        }
    }
    if(vis[x2][y2]==0)
    {
        cout<<-1<<endl;
    }
    else
    {
        cout<<v[x2][y2]<<endl;
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    int t = 1, tt=1;
    // cin>>t;
    while(tt<=t)
    {
        // cout<<"Case #"<<tt<<": ";
        solve();
        tt++;
    }
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
}

Measured memory_bytes: 20240