#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ll long long
#define hii cout << "hii" << endl
#define int long long
#define endl '\n'
#define all(s) s.begin(), s.end()
 
template <class T> ostream& operator << (ostream &os, const vector<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T> ostream& operator << (ostream &os, const set<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T, class S> ostream& operator << (ostream &os, const pair<T, S> &v) { os << v.first << ' ' << v.second; return os; }
template <class T, class S> ostream& operator << (ostream &os, const unordered_map<T, S> &v) { for (auto i : v) os << '(' << i.first << "=>" << i.second << ')' << ' '; return os; }
 
 
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <class Arg1> void __f(const char* name, Arg1&& arg1) { cerr << name << " : " << arg1 << endl; }
    template <class Arg1, class... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args) {
        const char* sep = strchr(names + 1, ',');
        cerr.write(names, sep - names) << " : " << arg1 << "  ";
        __f(sep + 1, args...);
    }
#else
#define trace(...) 0
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("avx2,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#endif // ifndef ONLINE_JUDGE

const int N = 5e5 + 5;
const int MAX = 250000 + 5;
const int M = 5e6 + 5;
const int mod = 1e9 + 7;
const int MOD = 998244353;
const int INF = 1e15;
const int LG = 21;

int arr[N];
int brr[N];

void solve()
{
	int n, m;
	cin >> n >> m;
	int a, b;
	cin >> a >> b;
	int c, d;
	cin >> c >> d;
	vector<vector<char>> arr(n + 1, vector<char>(m + 1));
	vector<vector<int>> dist(n + 1, vector<int>(m + 1, INF));
	// vector<vector<int>> dist(n + 1, vector<int>(m + 1, INF));
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			cin >> arr[i][j];
		}
	}
	vector<int> dx = {1, 0, -1, 0};
	vector<int> dy = {0, 1, 0, -1};
	set<pair<int, pair<int, int>>> q;
	q.insert({0, {a, b}});
	dist[a][b] = 0;
	while(q.size())
	{
		auto it = *q.begin();
		int x = it.second.first;
		int y = it.second.second;
		q.erase(q.begin());
		for(int i = 0; i < 4; i++)
		{
			int tempx = x + dx[i];
			int tempy = y + dy[i];
			if(tempx > n or tempx < 1) continue;
			if(tempy > m or tempy < 1) continue;
			if(arr[tempx][tempy] == '#') continue;
			if(dist[tempx][tempy] > dist[x][y])
			{
				q.erase({dist[tempx][tempy], {tempx, tempy}});
				dist[tempx][tempy] = dist[x][y];
				q.insert({dist[tempx][tempy], {tempx, tempy}});
			}
		}
		for(int i = x - 2; i < x + 3; i++)
		{
			for(int j = y - 2; j < y + 3; j++)
			{
				int tempx = i;
				int tempy = j;
				if(tempx > n or tempx < 1) continue;
				if(tempy > m or tempy < 1) continue;
				if(arr[tempx][tempy] == '#') continue;
				if(dist[tempx][tempy] > 1 + dist[x][y])
				{
					q.erase({dist[tempx][tempy], {tempx, tempy}});
					dist[tempx][tempy] = 1 + dist[x][y];
					q.insert({dist[tempx][tempy], {tempx, tempy}});
				}
			}
		}
	}
	if(dist[c][d] == INF) cout << -1 << endl;
	else cout << dist[c][d] << endl;
}
 
int32_t main() 
{	
	ios_base:: sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	    int t = 1;
	    // cin >> t;
	while(t--)solve();
	return 0;
}

Measured memory_bytes: 12720