#include <iostream>
#include <iomanip>
#include <string>
#include <string.h>
#include <math.h>
#include <cmath>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <algorithm>
#include <utility>
#include <deque>
#include <queue>
#include <functional>
//#include <boost/multiprecision/cpp_int.hpp>

#define rep(i, n) for(int i = 0; i < n; ++i)
#define REP(i, m, n) for(int i = m; i < n; ++i)
#define rrep(i,n) for(int i = n; i >= 0; --i)
#define RREP(i, m, n) for(int i = n; i >= m; --i)
#define llrep(i, n) for(ll i = 0; i < n; ++i)
#define llREP(i, m, n) for(ll i = m; i < n; ++i)
#define llrrep(i,n) for(ll i = n; i >= 0; --i)
#define llRREP(i, m, n) for(ll i = n; i >= m; --i)

using ll = long long;
using ull = unsigned long long;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
using pil = std::pair<int, long long>;
using pli = std::pair<long long, int>;
using plpii = std::pair<long long, std::pair<int, int>>;
using pdd = std::pair<double, double>;

const long long INF = 1000000000000000001;
const long long _MOD = 1000000007;
const long long MOD = 998244353;
const int ALPHABET = 27;
const double pi = 3.14159265358979;

using namespace std;
//namespace mp = boost::multiprecision;

struct node {
	ll distance;
	int pre;
	vector<pil> conected;
};

void dikstra(node* nodes, int n) {
	priority_queue<pli, vector<pli>, greater<pli>> que;
	rep(i, n) que.push(pli(nodes[i].distance, i));

	while (!que.empty()) {
		pli t = que.top();
		que.pop();
		if (t.first > nodes[t.second].distance) continue;

		rep(i, nodes[t.second].conected.size()) {
			if (nodes[nodes[t.second].conected[i].first].distance > nodes[t.second].distance + nodes[t.second].conected[i].second) {
				nodes[nodes[t.second].conected[i].first].distance = nodes[t.second].distance + nodes[t.second].conected[i].second;
				nodes[nodes[t.second].conected[i].first].pre = t.second;

				que.push(pli(nodes[nodes[t.second].conected[i].first].distance, nodes[t.second].conected[i].first));
			}
		}
	}
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int h, w;
	cin >> h >> w;
	pii c, d;
	cin >> c.first >> c.second;
	cin >> d.first >> d.second;
	string* s = new string[h];
	rep(i, h) cin >> s[i];

	node* nodes = new node[h*w];
	rep(i, h) {
		rep(j, w) {
			if (i == c.first - 1 && j == c.second - 1) nodes[i*w+j].distance = 0;
			else nodes[i*w+j].distance = INF;

			if (s[i][j] == '.') {
				if (i != 0 && s[i - 1][j] == '.') nodes[i*w+j].conected.push_back(pii((i - 1)*w + j, 0));
				if (i != h - 1 && s[i + 1][j] == '.') nodes[i*w + j].conected.push_back(pii((i + 1)*w + j, 0));
				if (j != 0 && s[i][j - 1] == '.') nodes[i*w + j].conected.push_back(pii(i*w + j - 1, 0));
				if (j != w - 1 && s[i][j + 1] == '.') nodes[i*w+j].conected.push_back(pii(i*w + j + 1, 0));

				rep(a, 5) {
					if (i - 2 + a >= 0 && i - 2 + a < h) {
						rep(b, 5) {
							if (j - 2 + b >= 0 && j - 2 + b < w) {
								if (s[i-2+a][j - 2 + b] == '.') {
									nodes[i*w + j].conected.push_back(pii((i - 2 + a)*w + (j - 2 + b), 1));
								}
							}
						}
					}
				}
			}
		}
	}

	dikstra(nodes, h*w);

	ll ans = nodes[(d.first - 1)*w + (d.second - 1)].distance;
	if (ans == INF) {
		cout << "-1" << "\n";
	}
	else {
		cout << nodes[(d.first - 1)*w + (d.second - 1)].distance << "\n";
	}

	return 0;
}


Measured memory_bytes: 229884