// Problem : D - Wizard in Maze
// Contest : AtCoder - AtCoder Beginner Contest 176
// URL : https://atcoder.jp/contests/abc176/tasks/abc176_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
ordered_set;	

#define FOR(i,a,b) for(int i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(int i = (a); i >= (b); --i)
#define RI(i,n) FOR(i,1,(n))
#define REP(i,n) FOR(i,0,(n)-1)
#define mini(a,b) a=min(a,b)
#define maxi(a,b) a=max(a,b)
#define pb push_back
#define st first
#define nd second
#define sz(w) (int) w.size()
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<pii, int> para;
const ll inf = 1e18 + 7;
const ll maxN = 1e3 + 5;
const ll MOD = 1e9 + 7;

int n, m, x_s, y_s, x2, y2;
int blocked[maxN][maxN];
int color[maxN][maxN];
bool used[maxN][maxN];
int dist[maxN * maxN];
set<int> graph[maxN * maxN];

vector<pii> neigh = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

void BFS_cell(int i, int j, int col) {
	queue<pii> Q;
	Q.push({i, j});
	while (!Q.empty()) {
		pii u = Q.front(); Q.pop();
		// if (used[u.st][u.nd]) continue;
		// cout << u.st << " " << u.nd << endl;
		used[u.st][u.nd] = true;
		color[u.st][u.nd] = col;
		for (auto nn: neigh) {
			int xx = u.st + nn.st;
			int yy = u.nd + nn.nd;
			// cout << "neigh " << xx << " " << yy << endl;
			if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
			if (!used[xx][yy] && !blocked[xx][yy]) {
				used[xx][yy] = true;
				Q.push({xx, yy});
			}
		}
	}
	// cout << endl;
}

// sprawdz MODULO!
int main() {
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	cin >> x_s >> y_s;
	cin >> x2 >> y2;
	REP(i, n) {
		string s;
		cin >> s;
		REP(j, m) {
			if (s[j] == '#') blocked[i][j] = true;
			else blocked[i][j] = false;
		}
	}
	int col = 1;
	REP(i, n) {
		REP(j, m) {
			if (!used[i][j] && !blocked[i][j]) {
				BFS_cell(i, j, col++);
			}
		}
	}
	REP(i, n) {
		REP(j, m) {
			if (color[i][j] == 0) continue;
			FOR(k, -2, 2) {
				FOR(l, -2, 2) {
					int xx = i + k;
					int yy = j + l;
					if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
					if (color[xx][yy] != color[i][j] && color[xx][yy] != 0) {
						graph[color[i][j]].insert(color[xx][yy]);
						graph[color[xx][yy]].insert(color[i][j]);
					}
				}
			}
		}
	}
	REP(i, 1e6 + 1) {
		dist[i] = -1;
	}
	int start = color[x_s - 1][y_s - 1];
	dist[start] = 0;
	queue<int> Q;
	Q.push(start);
	while (!Q.empty()) {
		int u = Q.front(); Q.pop();
		// cout << u << endl;
		if (u == color[x2 - 1][y2 - 1]) break;
		for (auto x: graph[u]) {
			// cout << "edge " << x << endl;
			if (dist[x] == -1) {
				dist[x] = dist[u] + 1;
				Q.push(x);
			}
		}
	}
	cout << dist[color[x2 - 1][y2- 1]];
	return 0;
}
 


Measured memory_bytes: 82264