//include
//------------------------------------------
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>

#include <numeric>
#include <utility>
#include <complex>

#include <sstream>
#include <iostream>
#include <iomanip>

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <ctime>

// namespace
using namespace std;

// type alias
using ll = long long;
using ull = unsigned long long;
using comp = complex<double>;

// constant
static const ll MOD = 1000000007LL;
static const double PI = 3.14159265358979323846;

// conversion
inline ll toint(string s) { ll v; istringstream sin(s); sin >> v; return v; }
template<class t> inline string tostring(t x) { ostringstream sout; sout << x; return sout.str(); }

// print
#define RET(x) return cout << x << endl, 0;

// for loop
#define REP(i, a, b) for ((i) = (ll)(a);(i) < (ll)(b);(i)++)
#define REPD(i, a, b) for (ll i = (ll)(a);(i) < (ll)(b);(i)++)
#define REPI(v, vs) for (auto& v : vs)

//debug
#ifdef LOCAL_ENV
#define DUMP(x)  cerr << #x << " = " << (x) << endl
#define DEBUG(x) cerr << #x << " = " << (x) << " (l" << __LINE__ << ")" << " " << __FILE__ << endl
#else
#define DUMP(x)
#define DEBUG(x)
#endif

#define MAX_VALUE 9223372036854775807


using Edge = pair<ll, ll>;

struct Graph
{
	using Vertex = ll;
	ll vertex_count;
	vector<Edge> edges;

	Graph() : vertex_count(0LL), edges(0LL) {}
	Graph(ll vertex_count) : vertex_count(vertex_count), edges(0LL) {}

	void add_edge(const Edge& edge)
	{
		edges.emplace_back(edge);
	}

	vector<vector<tuple<Vertex, Vertex>>> get_adjacency_list() const
	{
		using EdgeWithInfo = tuple<Vertex, Vertex>;
		// �ӂ̗אڃ��X�g���쐬
		vector<vector<EdgeWithInfo>> adjancency_list(vertex_count);
		for (ll i = 0; i < edges.size(); ++i)
		{
			Vertex from, to;
			tie(from, to) = edges[i];
			adjancency_list[from].emplace_back(from, to);
		}
		return move(adjancency_list);
	}

	template<class EdgeInfo>
	vector<vector<tuple<Vertex, Vertex, EdgeInfo>>> get_adjacency_list(const vector<EdgeInfo>& infos) const
	{
		using EdgeWithInfo = tuple<Vertex, Vertex, EdgeInfo>;
		// �ӂ̗אڃ��X�g���쐬
		vector<vector<EdgeWithInfo>> adjancency_list(vertex_count);
		for (ll i = 0; i < edges.size(); ++i)
		{
			Vertex from, to;
			tie(from, to) = edges[i];
			const EdgeInfo& info = infos[i];
			adjancency_list[from].emplace_back(from, to, info);
		}
		return move(adjancency_list);
	}
};

// �n�_ s ����e�_�ւ̍ŒZ������Ԃ��܂��B
// �p�X���̂����݂��Ȃ��ꍇ�� -1 ��Ԃ��܂��B
// ���� lengths �̊e�v�f�͔񕉂ł���K�v������܂��B
pair<vector<ll>, vector<ll>> dijkstra(const Graph& graph, const vector<ll>& lengths, ll s = 0LL)
{
	using Vertex = ll;
	using Length = ll;

	if (graph.edges.size() != lengths.size())
		throw runtime_error("�O���t�̕ӂ̗v�f���ƕӂ̒����̗v�f���͈�v���Ă���K�v������܂��B");

	// �ӂ̗אڃ��X�g���쐬
	auto adjacency_list = graph.get_adjacency_list(lengths);

	// �A���S���Y���{��
	using VertexInfo = pair<Length, Vertex>;
	priority_queue<VertexInfo, vector<VertexInfo>, greater<VertexInfo>> queue;
	vector<Length> dists(graph.vertex_count, 1LL << 60);
	vector<Vertex> prev_vertices(graph.vertex_count, -1LL);

	dists[s] = 0LL;
	queue.emplace(dists[s], s);
	prev_vertices[s] = s;
	while (!queue.empty())
	{
		Length l;
		Vertex v;
		tie(l, v) = queue.top();
		queue.pop();
		if (dists[v] < l) continue;
		for (auto& edge : adjacency_list[v])
		{
			Vertex to = get<1>(edge);
			Length length = get<2>(edge);
			if (dists[to] > dists[v] + length)
			{
				dists[to] = dists[v] + length;
				queue.emplace(dists[to], to);
				prev_vertices[to] = v;
			}
		}
	}
	for (ll i = 0; i < graph.vertex_count; ++i)
	{
		if (prev_vertices[i] == -1LL)
			dists[i] = -1LL;
	}

	return { dists, prev_vertices };
}

int solve() {
	ll H, W;
	cin >> H >> W;
	ll Ch, Cw;
	cin >> Ch >> Cw;
	ll Dh, Dw;
	cin >> Dh >> Dw;
	--Ch, --Cw, --Dh, --Dw;

	vector<string> Ss(H);
	REPD(i, 0, H) cin >> Ss[i];

	auto get_index = [&](ll i, ll j) {
		return i * W + j; 
	};

	Graph g(H * W);
	vector<ll> lengths;
	vector<vector<bool>> is_checked(H, vector<bool>(W, false));
	REPD(i, 0, H) REPD(j, 0, W){
		if (Ss[i][j] == '#') continue;
		for (ll k = -2; k <= 2; ++k) {
			for (ll l = -2; l <= 2; ++l){
				if (k == 0 && l == 0) continue;
				if (i + k < 0 || H <= i + k) continue;
				if (j + l < 0 || W <= j + l) continue;
				if (Ss[i + k][j + l] == '#') continue;
				g.add_edge({get_index(i, j), get_index(i + k, j + l)});
				if ((k == 1 && l == 0) || (k == -1 && l == 0) || (k == 0 && l == 1) || (k == 0 && l == -1)) lengths.emplace_back(0);
				else lengths.emplace_back(1);				
			}
		}
	}

	auto dists = dijkstra(g, lengths, get_index(Ch, Cw)).first;
	RET(dists[get_index(Dh, Dw)]);

	return 0;
}

//main function
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	solve();
	// ll t;
	// cin >> t;
	// REPD(i, 0, t) solve();

	return 0;
}


Measured memory_bytes: 393164