#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> indexed_set;
typedef vector<int> vi;
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define sz(v) (int)v.size()
#define ll long long int
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define fill(a,v) memset(a,v,sizeof(a));
#define all(v) v.begin(),v.end()
#define rep(i, a, b) for(int i = a; i < b; i++)
#define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

#define trarr(a,n) rep(i,0,n) cerr<<a[i]<<" \n"[i==n-1];
#define trmat(g,n,m) rep(i,0,n)rep(j,0,m) cerr<<g[i][j]<<" \n"[i==m-1];
#define tr(...) cerr<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__)
template<typename S, typename T> 
ostream& operator<<(ostream& out,pair<S,T> const& p){out<<'('<<p.ff<<", "<<p.ss<<')';return out;}
template<typename T>
ostream& operator<<(ostream& out,vector<T> const& v){
int l=v.size();for(int i=0;i<l-1;i++)out<<v[i]<<' ';if(l>0)out<<v[l-1];return out;}
template<typename T>
void trace(const char* name, T&& arg1){cout<<name<<" : "<<arg1<<endl;}
template<typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "<<arg1<<" | ";trace(comma+1,args...);}

const ld PI = acos(-1);
const ld EPS = 1e-9;
const int inf = 1e9+10;
const ll INF = 1e18+10;
const int P = 1e9+7;
const int N = 2e5+10;
bool isValid(pii p, int n, int m){
	bool a1 = 0, a2 = 0;
	if(p.ff>=1 && p.ff <=n)a1 = 1;
	if(p.ss>=1 && p.ss <=m)a2 = 1;
	// tr(p, n, m, a1, a2);
	return a1&&a2;
}
void solve(int _t){
	int h, w;
	int cs, ce, ds, de;
	cin >> h >> w;
	cin >> cs >> ce;
	cin >> ds >> de;
	string grid[h];
	rep(i, 0, h){
		cin >> grid[i];
	}
	vi dx = {-2,-1, 0, 1, 2};
	vi dy = {-2, -1,0, 1, 2};
	deque<pair<pii, int>> q;
	q.push_back(mp(mp(cs, ce), 0));
	int dis[h+1][w+1];
	bool vis[h+1][w+1];
	rep(i, 0, h+1) rep(j, 0, w+1){
		dis[i][j] = inf;
		vis[i][j] = 0;
	}	
	vis[cs][ce] = 1;
	dis[cs][ce] = 0;
	while(!q.empty()){
		auto p = q.front();
		q.pop_front();
		// tr(p);
		pii u = p.ff;
		set<int> nbs;
		rep(i, 0, sz(dx)){
			rep(j, 0, sz(dy)){
				if(dx[i] == 0 && dy[j] == 0) continue;
				// tr(dx[i], )
				pii pt = mp(u.ff+dx[i], u.ss+dy[j]);
				if(!isValid(pt, h, w)) continue;
				// tr(u, pt, dis[pt.ff][pt.ss], grid[pt.ff-1][pt.ss-1]);

				// if((!vis[pt.ff][pt.ss]) && (grid[pt.ff-1][pt.ss-1] == '.')){
				// 	dis[pt.ff][pt.ss] = p.ss+1;
				// 	q.push(mp(pt, dis[pt.ff][pt.ss]));
				// 	vis[pt.ff][pt.ss] = 1;
				// }
				// else 
				if(grid[pt.ff-1][pt.ss-1] == '.'){
					if(dis[pt.ff][pt.ss] > p.ss+1){
						dis[pt.ff][pt.ss] = p.ss+1;
						// tr(pt, dis[pt.ff][pt.ss]);
						q.push_back(mp(pt, dis[pt.ff][pt.ss]));
					}
				}
			}
		}
		vector<pii> nbr;
		nbr.pb(mp(u.ff+1, u.ss));
		nbr.pb(mp(u.ff, u.ss+1));
		nbr.pb(mp(u.ff-1, u.ss));
		nbr.pb(mp(u.ff, u.ss-1));
		rep(i, 0, sz(nbr)){
				// if(!i && !j)continue;
				pii pt = nbr[i];
				// mp(u.ff+dx[i], u.ss+dy[i]);
				if(!isValid(pt, h, w)) continue;
				if(grid[pt.ff-1][pt.ss-1] == '.'){
					if(dis[pt.ff][pt.ss] > p.ss){
						dis[pt.ff][pt.ss] = p.ss;
						q.push_front(mp(pt, dis[pt.ff][pt.ss]));
					}
				}
		}

	}
	if(dis[ds][de] == inf){
		cout<<-1<<endl;
	}
	else{
		cout<<dis[ds][de]<<endl;
	}
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int t = 1;
	// cin >> t;
	rep(test, 1, t+1){
		solve(test);
	}
	return 0;
}  

Measured memory_bytes: 9712