#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define     ll          long long int
#define     ld          double
#define     REP(i,x,n)    for(ll i=x;i<n;i++)
#define     SZ(v)       (ll)v.size()
#define     endl        "\n"
#define     ff          first
#define     ss          second
#define     PQ_MIN      priority_queue <ll, vector<ll>, greater<ll> >
#define     PQ          priority_queue <int>
#define     pbds        tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define     setbit(x)   __builtin_popcount(x)
#define     prec(n)     fixed<<setprecision(n)
#define     pb(n)       push_back(n)
#define     mp(a,b)     make_pair(a,b)
#define     clr(n)      memset(n,0,sizeof(n))
#define     reset(n)    memset(n,-1,sizeof(n))
#define     ii          pair<ll,ll>
#define     vll         vector<ll>
#define     PI          3.1415926535897932384626433832795028841971693993751

using namespace std;
using namespace __gnu_pbds;
bool comp(pair<ll,ll> a,pair<ll,ll> b) {       }
const ll MOD=1e9+7;
void print(vector<vector<ll> >&v)
{
    ll n=v.size();
    ll m=v[0].size();
    cout<<"\n";
    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<m;j++)
            cout<<v[i][j]<<" ";
        cout<<"\n";
    }
}
void print(vector<ll>&v)
{
    ll n=v.size();
    cout<<"\n";
    for(ll i=0;i<n;i++)
    {
            cout<<v[i]<<" ";
    }
        cout<<"\n";

}
void print(set<ll>&s)
{

cout<<endl;

set<ll>::iterator it;
for(it=s.begin();it!=s.end();it++)
    cout<<*it<<" ";
cout<<endl;
}
ll __lcm(ll a,ll b)
{
    return ((a*b)/__gcd(a,b));
}
ll power(ll a,ll p)
{
    ll res=1;
    while(p>0)
    {
        if(p&1){
            res=(res*a)%MOD;
            p--;
        }
            a=(a*a)%MOD;
            p/=2;
    }

    return res%MOD;
}
const ll INF=1e16;
const int nxm=1e3+5;
long dis[nxm][nxm];
string s[nxm];
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
bool vis[nxm][nxm];
int n,m;

void bfs(int srcx,int srcy)
{
    dis[srcx][srcy]=0;

    deque<pair<int,int> > qq;

    qq.push_back({srcx,srcy});

    while(!qq.empty())
    {
        pair<int,int> f=qq.front();
        int x=f.ff,y=f.ss;
        qq.pop_front();

        if(vis[x][y])
            continue;
        vis[x][y]=1;

        for(int i=x-2;i<=x+2;i++)
        {
            for(int j=y-2;j<=y+2;j++)
            {
                int w=((abs(i-x)+abs(j-y))>1);

                if(i<1 || i>n || j<1 || j>m || vis[i][j] || s[i-1][j-1]=='#' || dis[i][j]<=dis[x][y]+w)
                    continue;

                dis[i][j]=dis[x][y]+w;
                if(w) qq.push_back({i,j});
                else qq.push_front({i,j});
            }
        }

    }
}

void solve(){



cin>>n>>m;

int srcx,srcy,desx,desy;

cin>>srcx>>srcy>>desx>>desy;

REP(i,0,n) cin>>s[i];

REP(i,1,n+1) REP(j,1,m+1) dis[i][j]=INT_MAX;

bfs(srcx,srcy);

//REP(i,1,n+1) {REP(j,1,m+1) cout<<dis[i][j]<<" ";cout<<endl;}

if(dis[desx][desy]==INT_MAX)
    cout<<"-1";
else
    cout<<dis[desx][desy];







}
int main(){
//    freopen("timber_input", "r", stdin);
//    freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	ll t=1;
//	cin>>t;
    REP(i,1,t+1)
    {
//    cout<<"Case #"<<i<<": ";
		solve();
    }
	return 0;
}
//  bitset<64>(x).to_ullong() // in my com  _ulong()
//  cout<<bitset<64>(ans).to_string().substr(64-m)<<endl;
/*

const int INF = 0x3f3f3f3f;


char s[100];

fgets(s,100,stdin);

stringstream stram(s);

string abc;

bool ok1=0,ok2=0;

while(stram>>abc)

ternary operator for(int i=0;i<23;i++) or while(r-l>eps)


*/


Measured memory_bytes: 13644