#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define speed ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long 
#define ull unsigned long long
#define db double
#define vi vector<ll>
#define vvi vector<vector<int> >
#define vvii vector<vector<pii> >
#define rep(i,a,b) for(int i=a;i<b;i++)
#define endl "\n"
#define pii pair<ll,ll>
#define piii pair<ll,pair<ll,ll> >
#define mem(a,b) memset(a , b , sizeof a ) ; 
#define pb push_back
#define pf push_front
#define F first 
#define S second 
#define mp make_pair
#define all(v) v.begin(),v.end()

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }

void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << endl;
	err(++it, args...);
}



#define deb1(a) cout<<#a<<"=*"<<a<<endl;
#define deb2(a) cout<<#a<<"=@"<<a<<endl;
#define deb3(a) cout<<#a<<"=#"<<a<<endl;
#define deb4(a,b) cout<<#a<<"="<<a<<" and "<<#b<<"="<<b<<endl;
#define deb5(a,b) cout<<#a<<"="<<a<<" and "<<#b<<"="<<b<<endl;


typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;


ll mod=1000000007;
ll vis[212345]={0};
vvi v(212345);
ll d[212345]={0};


ll pow(ll a, ll b, ll m)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*a)%m;
		b/=2;
		a=(a*a)%m;
	}
	return ans;
}


//extended euclidean algorithm( x is inverse of a wrt b onlt if gcd!=1)
ll gcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	ll x1,y1;
	ll d=gcd(b,a%b,x1,y1);
	x=y1;
	y=x1-y1*(a/b);
	return d;

}

ll mat[1009][1009];
ll dp[1009][1009];
ll h,w;

void dfs(ll r,ll c,ll z)
{
	if(!mat[r][c]) return;
	if(r<0||r>h-1||c<0||c>w-1) return;
	if(dp[r][c]!=-1&&dp[r][c]<=z) return;
	dp[r][c]=z;
	if(r>0&&mat[r-1][c]) dfs(r-1,c,z);
	if(c>0&&mat[r][c-1]) dfs(r,c-1,z);
	if(r<h-1&&mat[r+1][c]) dfs(r+1,c,z);
	if(c<w-1&&mat[r][c+1]) dfs(r,c+1,z);
	
	rep(i,0,5)
	{
		rep(j,0,5)
		{	ll rr=r-2+i;
		 	ll cc=c-2+j;
		 	if(rr<0||rr>h-1||cc<0||cc>w-1) continue;
	
			if(dp[r-2+i][c-2+j]==-1||dp[r-2+i][c-2+j]>z+1)dfs(r-2+i,c-2+j,z+1);
			//	dfs(r-2+i,c-2+j,z+1);
		}
		}	
}
int main()
{
speed

cin>>h>>w;
ll x1,y1,x2,y2;
cin>>x1>>y1;
cin>>x2>>y2;

rep(i,0,h)
{
	string s;
	cin>>s;
	rep(j,0,w)
	{
		mat[i][j]=(s[j]=='#')?0:1;
	}
}
rep(i,0,1009) rep(j,0,1009) dp[i][j]=1e18;

priority_queue<piii,vector<piii>,greater<piii> > pq;
pq.push({0,{x1-1,y1-1}});

while(!pq.empty())
{
	piii p=pq.top();
	pq.pop();
	ll r=p.S.F;
	ll c=p.S.S;
	ll z=p.F;
	
	if(!mat[r][c]) continue;
	if(r<0||r>h-1||c<0||c>w-1) continue;
	if(dp[r][c]!=-1&&dp[r][c]<z) continue;
	dp[r][c]=z;
	
	if(r>0&&mat[r-1][c]&&dp[r-1][c]>z) 
	{
		dp[r-1][c]=z;
		pq.push({z,{r-1,c}});
	}
	if(c>0&&mat[r][c-1]&&dp[r][c-1]>z) 
	{
		dp[r][c-1]=z;
		pq.push({z,{r,c-1}});
		
	}
	if(r<h-1&&mat[r+1][c]&&dp[r+1][c]>z) 
	{
		dp[r+1][c]=z;
		pq.push({z,{r+1,c}});
	}
	if(c<w-1&&mat[r][c+1]&&dp[r][c+1]>z)
	{
		dp[r][c+1]=z;
		pq.push({z,{r,c+1}});
	
	}
		
		
	rep(i,0,5)
	{
		rep(j,0,5)
		{	ll rr=r-2+i;
		 	ll cc=c-2+j;
		 	if(rr<0||rr>h-1||cc<0||cc>w-1) continue;
	
			if(dp[r-2+i][c-2+j]==-1||dp[r-2+i][c-2+j]>z+1) 
			{
				dp[rr][cc]=z+1;
				pq.push({z+1,{rr,cc}});
			}
			//	dfs(r-2+i,c-2+j,z+1);
		}
	}	
	
}

//dfs(x2-1,y2-1,0);
//dp[x2-1][y2-1]=(dp[x2-1])
cout<<((dp[x2-1][y2-1]==1e18)?-1:dp[x2-1][y2-1])<<endl;

}



Measured memory_bytes: 24912