#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define forn(i,a,b) for(int i =a;i<b;i++)
#define fi first
#define se second
#define fast ios_base::sync_with_stdio(false);
using namespace std;

//for debugging 
/*
g++ -D_GLIBCXX_ASSERTIONS -DDEBUG -ggdb3 -std=c++14 
*/
int recur_depth = 0;
#ifdef DEBUG
#define dbg(x) {++recur_depth; auto x_=x; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<__LINE__<<"\t"<<#x<<" = "<<x_<<"\e[39m"<<endl;}
#else
#define dbg(x)
#endif
template<typename Ostream, typename Cont>
typename enable_if<is_same<Ostream,ostream>::value, Ostream&>::type operator<<(Ostream& os,  const Cont& v){
	os<<"[";
	for(auto& x:v){os<<x<<", ";}
	return os<<"]";
}
template<typename Ostream, typename ...Ts>
Ostream& operator<<(Ostream& os,  const pair<Ts...>& p){
	return os<<"{"<<p.first<<", "<<p.second<<"}";
}
// debugging ends here

typedef long long int ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<ll> vl;
const int mxn = 1e3+99;
// const int inf = 1e9;
int cache[mxn][mxn];
int h,w;
char maze[mxn][mxn];
const int mxa = 1e6+10; 
set<int> adj[mxa];

int dx[4] = {-1,0,0,1},dy[4]={0,-1,1,0};
bool pos(int x, int y){
	if(x<0 || x>=h) return false;
	if(y<0 || y >=w) return false;
	if(maze[x][y]=='#') return false;
	return true;
}

void dfs(int x,int y,int com){
	// cout << x << ""  << y << endl;
	cache[x][y] = com;
	for(int i =0;i<4;i++){
		int nx = x+dx[i];
		int ny = y+dy[i];
		if(pos(nx,ny) && cache[nx][ny]==-1){
			cache[nx][ny] = com;
			dfs(nx,ny,com);
		}
	}
}
int ans =1e9;

vector<int>  vis;

void solve(){
	
	// int h,w;
	cin >> h >> w;
	int sx,sy,tx,ty;
	cin >> sx >> sy >> tx >> ty;
	sx--,sy--;tx--,ty--;
	for(int i =0;i<h;i++){
		for(int j =0;j<w;j++){
			cin >> maze[i][j];
			cache[i][j] = -1;
		}
	}	
	int comps = 0;
	for(int i =0;i<h;i++){
		for(int j =0;j<w;j++){
			if(pos(i,j) && cache[i][j]==-1){
				// cout << i << " " << j << endl;
				dfs(i,j,comps);
				comps++;
			}
		}
	}

	// now I will add the edges

	for(int i =0;i<h;i++){
		for(int j=0;j<w;j++){
			for(int xx = -2;xx<3;xx++){
				for(int yy = -2;yy<3;yy++){
					int nx = i+xx,ny = j+yy;
					if(pos(nx,ny)&&pos(i,j)){
						if(cache[i][j]!=cache[nx][ny]){
							if(cache[i][j]>=0 && cache[nx][ny]>=0){
								// cout << i << " " << j<< " " << nx << " " << ny << endl;
								adj[cache[i][j]].insert(cache[nx][ny]);
								adj[cache[nx][ny]].insert(cache[i][j]);
							}
						}
					}
				}
			}
		}
	}

	// now just find the shortest path from x to y;
	// cout << "done" << endl;
	vis = vector<int> (comps,0);
	if(cache[tx][ty]==-1 || cache[sx][sy]==-1){
		cout << -1 << endl;return;
	}
	int s= cache[sx][sy];
	int t =cache[tx][ty];
	// dbg(adj); 
	if(s==t && s!=-1){

		cout << 0 << endl;
	}
	else{
		queue<pair<int,int > > bfs;
		bfs.push({s,0});
		vis[s] = 1;
		while(!bfs.empty()){
			pair<int,int > u =bfs.front();
			bfs.pop();
			for(auto v:adj[u.fi]){
				if(!vis[v]){
					// cout << v << endl;
					vis[v] = 1;
					bfs.push({v,u.se+1});
					if(v==t){
						cout << u.se+1 << endl;return;
					}
				}
			}
		}
		// cout << (ans>=1e9?-1:ans) << endl;
		// cout << ans << endl;
		cout << -1 << endl;
	}

	// jst need to check dp[tx][ty]
}

int main(){
	fast;
	#ifndef ONLINE_JUDGE
		freopen("input.txt","r",stdin);
		freopen("output.txt","w",stdout);
	#endif

	// int t;cin >> t;while(t--)
		solve();
}


Measured memory_bytes: 74520