// clang-format off
	#include <bits/stdc++.h>
	using namespace std; using ll = long long; using uint = unsigned int; using ull = unsigned long long;
	#define SFINAE(x, ...)	template <class, class = void> struct x : false_type {}; template <class T> struct x<T, void_t<__VA_ARGS__>> : true_type {};
	SFINAE(DefaultIO, decltype(cout << declval<T &>()))
	SFINAE(IsTuple, typename tuple_size<T>::type)
	SFINAE(Iterable, decltype(begin(declval<T>())))
	template <class T> constexpr char Space(const T &) { return (Iterable<T>::value or IsTuple<T>::value) ? '\n' : ' '; }
	template <auto &os> struct Writer {
		template <class T> void Impl(T const &t) const {
			if constexpr (DefaultIO<T>::value) os << t;
			else if constexpr (Iterable<T>::value) { int i = 0; for (auto &&x : t) ((i++) ? (os << Space(x), Impl(x)) : Impl(x)); }
			else if constexpr (IsTuple<T>::value) apply([this](auto const &... args) { int i = 0; (((i++) ? (os << ' ', Impl(args)) : Impl(args)), ...);}, t);
			else static_assert(IsTuple<T>::value, "No matching type for print");
		}
		template <class F, class... Ts> auto &operator()(F const &f, Ts const &... ts) const { return Impl(f), ((os << ' ', Impl(ts)), ...), os << '\n', *this; }
	};
	template <auto &is> struct Reader {
		template <class T> auto& Rd(T &t) const {
			if constexpr (DefaultIO<T>::value) is >> t;
			else if constexpr (Iterable<T>::value) for (auto &x : t) Rd(x);
			else if constexpr (IsTuple<T>::value) apply([this](auto &... args) { (Rd(args), ...); }, t);
			else static_assert(IsTuple<T>::value, "No matching type for read");
			return *this;
		}
		template <class T> auto operator[](T t) const { Rd(t); return t; }
		template <class... Ts> auto operator()(Ts... ts) const { (Rd(ts), ...); return tuple{move(ts)...}; }
	};
	#ifdef NARUT_LOCAL
	#define Debug(...) cerr << "\033[0;31m", Writer<cerr>{}(__VA_ARGS__), cerr << "\033[0m"
	#define ASSERT(...) if(not(__VA_ARGS__)) throw runtime_error("local assertion failed")
	#define LOCAL_ONLY(...) __VA_ARGS__
	#else
	#define Debug(...) 0
	#define ASSERT(...) 0
	#define LOCAL_ONLY(...) 0;
	#endif
	[[maybe_unused]] constexpr Reader<cin> Cin; [[maybe_unused]] constexpr Writer<cout> Cout;
	#define FOR(i, j, n) for (int i = int(j); i < int(n); ++i)
	#define ROF(i, j, n) for (int i = int(n) - 1; i >= int(j); --i)
	#define let auto const

// clang-format on



struct GridIndex {
	uint n, m;
	static constexpr array deltas = {array{-1, 0}, array{0, -1}, array{1, 0}, array{0, 1}};
	GridIndex(uint n, uint m) : n(n), m(m) {}
	bool In(uint i, uint j) const { return i < n and j < m; }
	template <class Func> void DoAdjacents(uint i, uint j, Func &&func) const {
		for (auto [u, v] : deltas)
			if (In(i + u, j + v)) func(i + u, j + v);
	}
	auto GetAdjacents(uint i, uint j) const {
		vector<array<uint, 2>> pairs;
		DoAdjacents(i, j, [&pairs](uint u, uint v) { pairs.push_back({u, v}); });
		return pairs;
	}
};


template <class T> using MaxPQ = priority_queue<T>;
template <class T> using MinPQ = priority_queue<T, vector<T>, greater<>>;


auto Main() {
	let [h,w] = Cin(0,0);
	auto C = Cin[pair(0u,0u)];
	auto D = Cin[pair(0u,0u)];
	let G = Cin[vector<string> (h)];

	C.first--,C.second--;
	D.first--,D.second--;

	vector<vector<uint>> dist(h, vector<uint> (w, -1));
	MinPQ<array<uint,3>> pq;
	pq.push({0, C.first, C.second});
	dist[C.first][C.second] = 0;

	GridIndex gi(h,w);
	while(pq.size()) {
		auto [d,i,j] = pq.top();
		pq.pop();
		if(dist[i][j] != d) continue;

		gi.DoAdjacents(i, j,[&,&d=d](uint u, uint v) {
			if(G[u][v] == '#') return;
			if(d < dist[u][v]) {
				dist[u][v] = d;
				pq.push({d, u, v});
			}
		});
		FOR(di,-2,3) {
			auto u = i+di;
			if(u >= h) continue;
			FOR(dj,-2,3) {
				auto v = j+dj;
				if(v >= w) continue;
				if(G[u][v]=='#') continue;
				if(d+1 < dist[u][v]) {
					dist[u][v] = d+1;
					pq.push({d+1, u, v});
				}
			}
		}
	}
	cout << (int)dist[D.first][D.second];
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(10);
#ifdef NARUT_LOCAL
	assert(freopen("io/test.in", "r", stdin));
	cin.exceptions(cin.badbit | cin.failbit);
	cerr << fixed << setprecision(10);
#endif

	Main();
}


Measured memory_bytes: 8528