// #define _GLIBCXX_DEBUG
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
using ll = long long; using pii = pair<int, int>; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>;
#define rep0(TMS) for (int CNT = 0; CNT < (int)(TMS); CNT++)
#define rep(CNT, GOAL) for (int CNT = 0; CNT < (int)(GOAL); CNT++)
#define rep2(CNT, START, GOAL) for (int CNT = (int)(START); CNT < (int)(GOAL); CNT++)
#define rep3(CNT, START, GOAL) for (int CNT = (int)(START); CNT > (int)(GOAL); CNT--)
#define all(CONT) begin(CONT), end(CONT)
#define itrep(ITR, CONT) for (auto ITR = begin(CONT); ITR != end(CONT); ITR++)
#define itrep1(ITR, CONT) for (auto ITR = next(begin(CONT)); ITR != end(CONT); ITR++)
template <typename T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template <typename T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }
void prec(const int &DIG) { cerr << fixed << setprecision(DIG); cout << fixed << setprecision(DIG); }
template <typename T> void CERR(const T &ELEM) { cerr << ELEM; }
template <typename T, typename ...Ts> void CERR(const T &FIRST, const Ts &...REST) { CERR(FIRST); cerr << ", "; CERR(REST...); }
template <typename T1, typename T2> void CERR(const pair<T1, T2> &PAIR) { cerr << "("; CERR(PAIR.first); cerr << ", "; CERR(PAIR.second); cerr << ")"; }
template <typename T> void CERR(const vector<T> &VEC) { cerr << "{ "; itrep(ITR, VEC) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T> void CERR1(const vector<T> &VEC) { cerr << "{ "; itrep1(ITR, VEC) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T> void CERR(const set<T> &SET) { cerr << "{ "; itrep(ITR, SET) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T> void CERR(const multiset<T> &MULTISET) { cerr << "{ "; itrep(ITR, MULTISET) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T1, typename T2> void CERR(const map<T1, T2> &MAP) { cerr << "{ "; itrep(ITR, MAP) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
#define db(OBJ) cerr << #OBJ << ": "; CERR(OBJ); cerr << ", "
#define dbl(OBJ) cerr << #OBJ << ": "; CERR(OBJ); cerr << "\n"
#define db1(OBJ) cerr << #OBJ << ": "; CERR1(OBJ); cerr << "\n"
#define dbs(...) cerr << "(" << #__VA_ARGS__ << "): ("; CERR(__VA_ARGS__); cerr << ")\n"
#define dbvv(VV) cerr << #VV << ": {\n"; rep(CNT, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db01(VV) cerr << #VV << ": {\n"; rep(CNT, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR1(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db10(VV) cerr << #VV << ": {\n"; rep2(CNT, 1, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db11(VV) cerr << #VV << ": {\n"; rep2(CNT, 1, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR1(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define YN(FLG) cout << (FLG ? "YES" : "NO") << "\n"
#define Yn(FLG) cout << (FLG ? "Yes" : "No") << "\n"
#define yn(FLG) cout << (FLG ? "yes" : "no") << "\n"
// const ll INF = 1'000'000'000'000'000'007;
const int INF = 1'000'000'007;
const ll MOD = 1'000'000'007; // 998'244'353;

int H, W, Ch, Cw, Dh, Dw;
vvi g, dis;

// priority_queueを使う
void bfs(int si, int sj) {
	vi dx = { 1, 0, -1, 0 }, dy = { 0, 1, 0, -1 };
	// queue<pii> q;
	priority_queue<pair<int, pii>, vector<pair<int, pii>>, greater<pair<int, pii>>> q;
	dis[si][sj] = 0; q.push(make_pair(dis[si][sj], pii(si, sj)));
		
	while (!q.empty()) {
		int di = q.top().first;
		int ui = q.top().second.first;
		int uj = q.top().second.second;
		q.pop();

		rep(k, 4) {
			int vi = ui + dx[k], vj = uj + dy[k];
			if (vi < 0 or H <= vi or vj < 0 or W <= vj) continue;
			if (!g[vi][vj]) continue;
			if (chmin(dis[vi][vj], dis[ui][uj])) q.push(make_pair(dis[vi][vj], pii(vi, vj)));
		}
		rep2(di, -2, 3) {
			rep2(dj, -2, 3) {
				int vi = ui + di, vj = uj + dj;
				if (vi < 0 or H <= vi or vj < 0 or W <= vj) continue;
				if (!g[vi][vj]) continue;
				if (dis[ui][uj] + 1 >= dis[vi][vj]) continue;
				dis[vi][vj] = dis[ui][uj] + 1;
				q.push(make_pair(dis[vi][vj], pii(vi, vj)));
			}
		}
	}
}

int main() {
	// 0-ind
	cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
	Ch--; Cw--; Dh--; Dw--;
	g = vvi(H, vi(W));
	dis = vvi(H, vi(W, INF));
	
	rep(i, H) {
		string S; cin >> S;
		// dbl(S);
		rep(j, W) g[i][j] = S[j] == '.'; // true: 通過できる道
	}

	// dbvv(g);
	
	// dfs(Ch, Cw);
	bfs(Ch, Cw);
	// dbvv(dis);

	int ans = dis[Dh][Dw];
	if (ans == INF) ans = -1;

	cout << ans << endl;
}

Measured memory_bytes: 11468