#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <cmath>
#include <limits>
#define ALL(x) (x).begin(),(x).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define int_INF 2147483647
#define pint_INF 2000000000
#define ll_INF 	9223372036854775807
#define MOD 1000000007
#define vi vector<int>
#define vvi vector<vector<int>>
#define vvll vector<vector<long long>>
#define vvc vector<vector<char>>
#define vll vector<long long>
#define pii pair<int,int>
#define vpii vector<pair<int,int>>
#define sysp system("PAUSE")
#define pno cout << "no" << endl
#define pyes cout << "yes" << endl
#define pYes cout << "Yes" << endl
#define pNo cout << "No" << endl
#define pNO cout << "NO" << endl
#define pYES cout << "YES" << endl
using namespace std;
using ll = long long;
#define int ll

vector<int> operator+(const vi & v1, const vi & v2) {
	return { v1[0] + v2[0],v1[1] + v2[1] };
}

bool isWithin(const vi& now, vvi& vec) {
	int y = now[0];
	int x = now[1];
	if (-1 < y && y < vec.size()) {
		if (-1 < x && x < vec[0].size()) {
			//Condition
			if (vec[y][x] == 0) {
				return true;
			}
			else {
				return false;
			}
			
		}
	}
	return false;
}

void dfs(vector<vector<int>>& vec, int startX, int startY,int paintNum) {
	vvi moves = { {-1,0},{1,0},{0,1},{0,-1} };
	vi start = { startY,startX };

	stack<vi> st;
	st.push(start);

	while (!st.empty()) {
		vi now = st.top(); st.pop();
		vec[now[0]][now[1]] = paintNum;
		for (int m = 0; m < 4; m++) {
			vi cor = now + moves[m];
			if (isWithin(cor, vec)) {
				st.push(cor);
			}
		}
	}
	return;
}

bool comp(const vector<int>& a, const vector<int>& b) {
	if (a[1] != b[1]) {
		return a[1] > b[1];
	}
	else {
		return a[0] < b[0];
	}
}

struct Node {
public:
	bool isVisited;
	set<vector<int>> to_child; // {node_number,weight}
};

//startを起点にするDjikstra {NodeNumber,CostfromStart}
vector<int> Dijkstra(vector<Node> Graph_V, int start) {
	vector<int> Cost(Graph_V.size(), pint_INF);
	priority_queue<vector<int>, vector<vector<int>>, decltype(&comp)> pq(&comp);
	Cost[start] = 0;
	pq.push({ start,0 });

	while (!pq.empty()) {
		int parent = pq.top()[0]; pq.pop();
		Node u = Graph_V[parent];
		if (Graph_V[parent].isVisited == true) continue;
		Graph_V[parent].isVisited = true;
		for (vector<int> child : u.to_child) {
			if (Cost[parent] + child[1] < Cost[child[0]]) {
				Cost[child[0]] = Cost[parent] + child[1];
				pq.push({ child[0],Cost[child[0]] });
			}
		}
	}

	return Cost;
}

signed main() {
	int H, W; cin >> H >> W;
	int ch, cw; cin >> ch >> cw;
	ch--; cw--;
	int dh, dw; cin >> dh >> dw;
	dh--; dw--;

	vector<vector<int>> input(H, vi(W));
	rep(i, H) rep(j, W) {
		char c; cin >> c;
		if (c == '.') {
			input[i][j] = 0;
		}
		else {
			input[i][j] = - 1;
		}
	}
	int tmp = 1;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (input[i][j] == 0) {
				dfs(input, j, i, tmp);
				tmp++;
			}
		}
	}
	// we have tmp -1 groups
	vector<Node> graph(tmp - 1);

	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (input[i][j] > 0) {
				//search 5x5 and complie
				int zero = 0;
				int miny = max(zero, i - 2);
				int maxy = min(H - 1, i + 2);
				int minx = max(zero, j - 2);
				int maxx = min(W - 1, j + 2);

				set<int> st;
				for (int y = miny; y <= maxy; y++) {
					for (int x = minx; x <= maxx; x++) {
						if (input[y][x] > 0) {
							st.insert(input[y][x]);
						}
					}
				}

				for (auto iter = st.begin(); iter != st.end(); iter++) {
					graph[input[i][j]-1].to_child.insert({ *iter - 1,1 });
				}
			}
		}
	}

	vector<int> dji = Dijkstra(graph, input[ch][cw]-1);

	int ans = dji[input[dh][dw] - 1];
	if (ans == pint_INF) {
		cout << -1 << endl;
	}
	else {
		cout << dji[input[dh][dw] - 1] << endl;
	}
}

Measured memory_bytes: 124680