/*
Dont BLUNDER
*/
#include<bits/stdc++.h>
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;


 */
#define d long double
#define int long long
#define pii pair<int,int>
#define pb push_back
#define endl '\n'
#define pi acos(-1)

#define init(x,a) memset(x,a,sizeof(x))
#define all(c) c.begin(),c.end()
int const mod1 = 998244353;
int const mod = 1000000007;
#define l first
#define r second
int toint(const string &s) {stringstream ss; ss << s; int x; ss >> x; return x;}
string tostring ( int number ) {stringstream ss; ss << number; return ss.str();}
#define out(x) cout<<#x<<" = "<<" "<<x<<"\n";
#define trace1(x)                cerr<<#x<<": "<<x<<endl
#define trace2(x, y)             cerr<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x, y, z)          cerr<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define haha ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
// * Using PBDS *
/*typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update>
               os; */



int modexp(int x, int n) {
	if (n == 0) {
		return 1;
	}
	else if (n & 1) {
		return (modexp((x * x) % mod, n / 2) % mod * x % mod) % mod;
	}
	else {
		return (modexp((x * x) % mod, n / 2) % mod);
	}
}

int modinv(int n)
{
	return modexp(n, mod - 2);
}

int gcd(int a, int b) {
	if (b == 0) {
		return a;
	}
	return gcd(b, a % b);
}
bool comp(pii a, pii b) {
	return a.second < b.second;

}

vector<pii> adj[1000001];
int dis[1000001];




signed main()
{
	haha
#ifndef ONLINE_JUDGE

	freopen("inp.txt", "r", stdin);

	freopen("out1.txt", "w", stdout);
#endif
	for (int i = 0; i <= 1000000; i++)
		dis[i] = 100000000000;
	int m, n;
	cin >> n >> m;
	int x1, y1, x2, y2;
	cin >> x1 >> y1 >> x2 >> y2;
	--x1, --x2, --y1, --y2;
	int start = x1 * m + y1;
	int end = x2 * m + y2;
	char arr[n][m];
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			cin >> arr[i][j];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (arr[i][j] == '.') {
				int ind = i * m + j;
				for (int z = -2; z < 3; z++) {
					for (int k = -2; k < 3; k++) {
						if (k == 0 && z == 0)
							continue;
						if ((i + z < n && j + k < m && i + z >= 0 && j + k >= 0) && arr[i + z][j + k] == '.')
						{
							int ind1 = (i + z) * m + j + k;
							if ((z == 0 && k == 1) || (z == 1 && k == 0) || (z == -1 && k == 0) || (z == 0 && k == -1)) {
								adj[ind].pb({ind1, 0});
								adj[ind1].pb({ind, 0});
							}
							else {
								adj[ind].pb({ind1, 1});
								adj[ind1].pb({ind, 1});
							}
						}
					}
				}

			}
		}
	}
	dis[start] = 0;
	deque<int> q;
	q.push_back(start);
	int vis[1000001];
	init(vis, 0);
	vis[start] = 1;

	while (q.size()) {
		int t = q.front();
		q.pop_front();
		for (auto x : adj[t]) {
			if (vis[x.first] == 0) {
				int w = x.second;
				int ind = x.first;
				if (dis[ind] > (dis[t] + w))
				{
					if (w == 1)
						q.push_back(ind);
					else
						q.push_front(ind);
					dis[ind] = dis[t] + w;
				}
				//vis[ind] = 1;
			}


		}



	}
	// for (int i = 0; i < 20; i++) {
	// 	cout << i << endl;
	// 	for (auto x : adj[i])
	// 	{
	// 		cout << x.first << " " << x.second << endl;
	// 	}
	// 	cout << endl;
	// }
	if (dis[end] == 100000000000)
		cout << -1;
	else
		cout << dis[end];



















}

Measured memory_bytes: 299380