#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 int                     long long int
#define ld                      long double
#define pb                      push_back
#define MOD                     1000000007
#define inf                     3e18
#define vi                      vector<int>
#define vld                     vector<ld>
#define pii                     pair<int,int>
#define mii                     map<int,int>
#define fi                      first
#define se                      second
#define fastIO                  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define db(...)                 __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) { cerr << " "<< name << " : " << arg1 <<'\n'; }
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ',');
    cerr.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}

typedef tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds; 
		//order_of_key (k) : Number of items strictly smaller than k .
		//find_by_order(k) : K-th element in a set (counting from zero) (returns an iterator)           


void inp_out()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("debug.txt", "w", stderr);
	#endif
}

struct Dijkstra
{
	vector<int> p,dis;
	int n;
	vector<int> check;
	Dijkstra(int size)          
	{
		n=size;
		p.resize(n+1,-1);
		dis.resize(n+1,inf);
	}

	void build(int s,vector<vector<pair<int,int>>> adj)            //adj pair-->i.fi==node and i.se=cost better make vvpii adj global
	{
	 // 	db(s); 
		dis[s]=0;
	    set<pair<int,int>> q;
	    q.insert({0,s});
		while(!q.empty())
		{
			 // db(s); 
			int v = q.begin()->se;
			q.erase(q.begin());
			
			for(auto i:adj[v])
			{
			  //  	db(v, i.fi); 
				if(dis[i.fi]>dis[v]+i.se)
				{
					q.erase({dis[i.fi],i.fi});	
					dis[i.fi]=dis[v]+i.se;
					p[i.fi]=v;
					q.insert({dis[v]+i.se,i.fi});
				}
			}	
		}
	}
};

int32_t main()
{
	fastIO
	inp_out();
	int h, w; 

	cin >> h >> w; 

	int x, b, c, z; 

	cin >> x >> b >> c >> z; 

	-- x, -- b, -- c, -- z; 

	vector < string > a(h); 

	for(int i = 0; i < h; ++ i)
		cin >> a[i]; 

	vector < vector < pii >> adj(h * w + 1);

	Dijkstra d(h * w);  

	for(int i = 0; i < h; ++ i)
	{
		for(int j = 0; j < w; ++ j)
		{
			if(a[i][j] == '.')
			{
				for(int k =  - 2; k <=  2; ++ k)
				{
					for(int l =  - 2; l <= 2; ++ l)
					{
						if(k == 0 && l == 0)
							continue; 
						if(i + k >= 0 && i + k < h && j + l >= 0 && j + l < w && a[i + k][j + l] == '.')
						{
						   // 	db((i * w + j), ((i+k) * w + j + l + 1)); 
							if(k == 0 && (l == 1 || l ==  - 1))
								adj[i * w + j + 1].pb({(i + k) * w + j + l + 1, 0});
							else if(l == 0 && (k == 1 || k ==  - 1))
								adj[i * w + j + 1].pb({(i + k) * w + j + l + 1, 0});
							else adj[i * w + j + 1].pb({(i + k) * w + j + l + 1, 1}); 
						}
					}
				}
			}
		}
	}
 
	d.build(x * w + b + 1, adj); 

	cout << (d.dis[c * w + z + 1] == inf ?  - 1 : d.dis[c * w + z + 1]); 

	return 0;
}

Measured memory_bytes: 299808