/*
    ____       ____                 _
   |  _ \ _ __|  _ \  ___ _ __   __| |_ __ ___
   | | | | '__| | | |/ _ \ '_ \ / _` | '__/ _ \ 
   | |_| | |_ | |_| |  __/ | | | (_| | | | (_) |
   |____/|_(_)|____/ \___|_| |_|\__,_|_|  \___/
*/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define db1(x) cout << #x << "=" << x << '\n'
#define db2(x, y) cout << #x << "=" << x << "," << #y << "=" << y << '\n'
#define db3(x, y, z) cout << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << '\n'
#define rep(i, k, n) for (int i = k; k < n ? i < n : i > n; k < n ? i += 1 : i -= 1)
#define si(x) scanf("%d", &x)
#define sl(x) scanf("%lld", &x)
#define ss(x) scanf("%s", x)
#define pi(x) printf("%d\n", x)
#define pl(x) printf("%lld\n", x)
#define ps(x) printf("%s\n", x)
#define all(x) x.begin(), x.end()
#define clr(x) memset(x, 0, sizeof(x))
#define sortall(x) sort(all(x))
#define tr(it, a) for (auto it = a.begin(); it != a.end(); it++)
#define PI 3.1415926535897932384626
#define F first
#define S second
#define pb push_back
#define ll long long

typedef pair<int, int> pii;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pl> vpl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

int mpow(int base, int exp);
void ipgraph(int m);
void dfs(int u, int par);
const int mod = 1000000007;
const int N = 1e3+7, M = N, OO = 1e9 + 7;
const ll LLOO = 1e18 + 7;
//=======================

vi g[N];
int a[N],n,m,dist[N][N];
char c[N][N];
vector<pii> d1,d2;

bool check(int x,int y)
{
	return x >= 0 && y >= 0 && x < n && y < m && c[x][y] == '.';
}

int dijkstra(pii src,pii dest)
{
	rep(i,0,n) rep(j,0,m) dist[i][j] = OO;
	set<pair<int,pii> > q;
	q.insert({0,src});
	dist[src.F][src.S] = 0;
	
	while(!q.empty())
	{
		auto cur = *q.begin();
		q.erase(q.begin());
		//db3(cur.F,cur.S.F,cur.S.S);
		for(auto p:d1)
		{
			int nx = cur.S.F+p.F;
			int ny = cur.S.S+p.S;
			if (check(nx,ny) && dist[nx][ny] > cur.F)
			{
				dist[nx][ny] = cur.F;
				q.insert({cur.F,{nx,ny}});
			}
		}
		
		for (auto p:d2)
		{
			int nx = cur.S.F+p.F;
			int ny = cur.S.S+p.S;
			if (check(nx,ny) && dist[nx][ny] > cur.F+1)
			{
				dist[nx][ny] = cur.F+1;
				q.insert({cur.F+1,{nx,ny}});
			}
		}
	}
	
	return dist[dest.F][dest.S];
}

void solve()
{
    rep(i,-1,2) rep(j,-1,2)
    {
		if (abs(i) != abs(j)) d1.pb({i,j});
	}
	
	rep(i,-2,3) rep(j,-2,3)
    {
		d2.pb({i,j});
	}
	
	si(n);
	si(m);
	
	pii src;
	si(src.F);
	si(src.S);
	src.F--;
	src.S--;
	pii dest;
	si(dest.F);
	si(dest.S);
	dest.F--;
	dest.S--;
	
	rep(i,0,n) ss(c[i]);
	
	int ans = dijkstra(src,dest);
	
	pi(ans == OO ? -1:ans);
	
}

int main()
{
    // uncomment if file :
    // freopen("in","r",stdin);
    // freopen("out","w",stdout);
    int t = 1;
    // si(t); // uncomment if testcases
    while (t--)
        solve();
    return 0;
}

int mpow(int base, int exp)
{
    base %= mod;
    int result = 1;
    while (exp > 0)
    {
        if (exp & 1)
            result = ((ll)result * base) % mod;
        base = ((ll)base * base) % mod;
        exp >>= 1;
    }
    return result;
}

void ipgraph(int n, int m)
{
    int u, v;
    while (m--)
    {
        scanf("%d %d", &u, &v);
        g[u - 1].pb(v - 1);
        g[v - 1].pb(u - 1);
    }
}

void dfs(int u, int par)
{
    for (int v : g[u])
    {
        if (v == par)
            continue;
        dfs(v, u);
    }
}


Measured memory_bytes: 9320