#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<sstream>
#include<iterator>
#include<list>

using namespace std;

typedef  long long int lint;

#define rep(i, n) for (lint i = 0; i < n; i++)
#define sort(v) sort((v).begin(), (v).end())
#define reverse(v) reverse((v).begin(), (v).end())
#define upper(v,hoge) upper_bound(v.begin(),v.end(),hoge)
#define lower(v,hoge) lower_bound(v.begin(),v.end(),hoge)
#define mp make_pair
#define enld endl

using P = pair<int, int>;

int main() {
	int INF = 1 << 30;

	lint H, W;
	cin >> H >> W;
	lint CH, CW, DH, DW;
	cin >> CH >> CW >> DH >> DW;
	CH--;
	CW--;
	DH--;
	DW--;
	vector<vector<char>>S(H, vector<char>(W));
	rep(i, H) {
		rep(j, W) {
			cin >> S[i][j];
		}
	}
	vector<lint>di;
	vector<lint>dj;
	di = { 0,1,0,-1 };
	dj = { 1,0,-1,0 };

	// BFS
	vector<vector<int> > CL(H, vector<int>(W, INF));
	int color = -1;

	rep(ii, H) {
		rep(jj, W) {
			if (S[ii][jj] != '#') {
				if(CL[ii][jj]==INF){
				color++;
				CL[ii][jj] = color;
				queue<P> que;
				que.push(P(ii, jj));

				while (!que.empty()) {
					P pos = que.front();
					que.pop();
					int i = pos.first, j = pos.second;
					for (int k = 0; k < 4; k++) {
						int ni = i + di[k], nj = j + dj[k];
						if (ni < 0 || ni >= H) continue;
						if (nj < 0 || nj >= W) continue;
						if (S[ni][nj] == '#') continue;
						if (CL[ni][nj] > CL[i][j] + 1) {
							CL[ni][nj] = color;
							que.push(P(ni, nj));
						}
					}
					}
				}
			}
		}
	}
	/*
	rep(i, H) {
		rep(j, W) {
			cout << CL[i][j] << ' ';
		}
		cout << endl;
	}
	*/
	vector<pair<lint, lint>>GG;

	
	rep(ii, H) {
		rep(jj, W) {
			for (lint i = -2; i <= 2; i++) {
				for (lint j = -2; j <= 2; j++) {
					if (0 <= ii + i && ii + i < H) {
						if (0 <= jj + j && jj + j < W) {
							if (CL[ii][jj] != INF && CL[i + ii][j + jj] != INF) {
								if (CL[ii][jj] != CL[i + ii][j + jj]) {
									GG.push_back(P(CL[ii][jj], CL[i + ii][j + jj]));
								}
							}
						}
					}
				}
			}
		}
	}

	/*
	rep(i, GG.size()) {
		cout << GG[i].first << ' ' << GG[i].second << endl;
	}
	*/
	vector<set<lint>>SG(color+1);

	rep(i, GG.size()) {
		SG[GG[i].first].insert(GG[i].second);
	}

	vector<vector<lint>>G(color + 1);

	set<lint>::iterator it;

	rep(i, SG.size()) {
		for (it = SG[i].begin(); it != SG[i].end(); it++) {
			G[i].push_back(*it);
			//cout << *it << ' ';
		}
		//cout << enld;
	}
	/*
	rep(i, G.size()) {
		rep(j, G[i].size()) {
			cout << G[i][j] << ' ';
		}
		cout << endl;
	}
	*/
	vector<int>dist(color+1, INF);//startからの距離を入れる配列。INF(未訪問)で初期化
	queue<int> que;

	dist[CL[CH][CW]] = 0;
	que.push(CL[CH][CW]);

	//BFS
	while (!que.empty()) {
		int v = que.front();
		que.pop();

		for (int nv : G[v]) {
			if (dist[nv] != INF)continue;
			dist[nv] = dist[v] + 1;
			que.push(nv);
		}
	}

	if (dist[CL[DH][DW]] == INF) {
		cout << -1 << enld;
	}
	else {
		cout << dist[CL[DH][DW]] << endl;
	}

}

Measured memory_bytes: 64928