#include<bits/stdc++.h>
//#pragma GCC target ("avx2")
//#pragma GCC optimization ("Ofast")
using namespace std;

#ifdef ONLINE_JUDGE
#define cerr if (false) cerr
#endif

#define fora(i, a, b) for (int i = (a); i < (b); i++)
#define ford(i, a, b) for (int i = (a); i >= (b); i--)
#define pr(x) cerr << #x << " = " << x << "\n";
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define ld(x) ((long double) x)

using ll = long long;
using ull = unsigned long long;

using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;

using vpii = vector<pii>;
using vpll = vector<pll>;
using vpdd = vector<pdd>;

const long double PI = 3.14159265358979323;
const long long MOD = 1e9 + 7;


mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); // uniform_int_distribution<int>(0, n)(rng)

ll rnd(ll n) {
    return uniform_int_distribution<ll>(0, n)(rng);
}

long double rndLD(ll n) {
    return uniform_real_distribution<long double>(0, n)(rng);
}

struct custom_hash { // unordered_map<long long, int, custom_hash> safe_map;
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return (size_t) splitmix64(x + FIXED_RANDOM);
    }
	size_t operator()(pair<uint64_t,uint64_t> x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return (size_t) (splitmix64(x.first + FIXED_RANDOM)^(splitmix64(x.second + FIXED_RANDOM) >> 1));
	}
};

ull modmul(ull a, ull b, ull M) {
	ll ret = a * b - M * ull(1.L / M * a * b);
	return ret + M * (ret < 0) - M * (ret >= (ll)M);
}

ll power(ll b, ll e, ll mod) {
	ull ans = 1;
	for (; e; b = modmul(b, b, mod), e /= 2)
		if (e & 1) ans = modmul(ans, b, mod);
	return ans;
}

long long modInverse(long long n, long long p) {
    return power(n, p-2, p);
}

long long ncr(long long arr[], long long n, long long r, long long p) {
    return ((arr[n] * modInverse(arr[r], p))%p * modInverse(arr[n-r], p))%p;
}

bool isPrime(ull n) {
	if (n < 2 || n % 6 % 4 != 1) return (n | 1) == 3;
	ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
	    s = __builtin_ctzll(n-1), d = n >> s;
	for (ull a : A) {   // ^ count trailing zeroes
		ull p = power(a%n, d, n), i = s;
		while (p != 1 && p != n - 1 && a % n && i--)
			p = modmul(p, p, n);
		if (p != n-1 && i != s) return 0;
	}
	return 1;
}

ull pollard(ull n) {
	auto f = [n](ull x) { return modmul(x, x, n) + 1; };
	ull x = 0, y = 0, t = 0, prd = 2, i = 1, q;
	while (t++ % 40 || __gcd(prd, n) == 1) {
		if (x == y) x = ++i, y = f(x);
		if ((q = modmul(prd, max(x,y) - min(x,y), n))) prd = q;
		x = f(x), y = f(f(y));
	}
	return __gcd(prd, n);
}

vector<ull> factor(ull n) {
	if (n == 1) return {};
	if (isPrime(n)) return {n};
	ull x = pollard(n);
	auto l = factor(x), r = factor(n / x);
	l.insert(l.end(), all(r));
	return l;
}

const int MAXN = 200005;
vector<int> prime;
bool is_composite[MAXN];
void sieve(int n) {
	fill(is_composite, is_composite + n, false);
	fora(i, 2, n) {
		if (!is_composite[i]) prime.push_back (i);
		for (int j = 0; j < (int) prime.size() && i * prime[j] < n; j++) {
			is_composite[i * prime[j]] = true;
			if (i % prime[j] == 0) break;
		}
	}
}

struct Node {
    int nr;
    vector<Node*> edges;
    vector<Node*> edges2;
    bool visited = false;
    bool active = false;
    int distance = 1e9;
    void reset() {
        visited = false;
        active = false;
        distance = 1e9;
    }
    void hardReset() {
        edges.clear();
        visited = false;
        active = false;
        distance = 1e9;
    }
};

void dfs(Node* node) {
    if (node -> visited) {
        return;
    }
    node -> visited = true;
    node -> active = true;
    for (Node* newNode: node -> edges) {
        if (!newNode -> active) {
            newNode -> distance = min(newNode -> distance, node -> distance + 1);
        }
        if (!newNode -> visited) {
            dfs(newNode);
        }
    }
    node -> active = false;
}

void bfs(Node* node) {
    if (node -> visited) {
        return;
    }
    node -> visited = true;
    node -> distance = 0;
    list<Node*> q;
    for (q.push_front(node); !q.empty(); ) {
        node = q.front();
        q.pop_front();
        for (Node* newNode: node -> edges) {
            if (newNode -> distance > node -> distance) {
                newNode -> distance = node -> distance;
                q.push_front(newNode);
            }
        }
        for (Node* newNode: node -> edges2) {
            if (newNode -> distance > node -> distance + 1) {
                newNode -> distance = node -> distance + 1;
                q.push_back(newNode);
            }
        }
    }
}


Node nodes[1003][1003];
int n,m,k,t,a,b,c,rez,sk,x,y;
char mas[1003][1003];
string s1,s2;
list<int> q;
set<int> s;
bool in(int a, int b) {
    return (a >= 0 && a < n && b >= 0 && b < m);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    cin >> a >> b;
    cin >> x >> y;
    fora(i, 0, n) {
        fora(j, 0, m) {
            cin >> mas[i][j];
        }
    }
    fora(i, 0, n) {
        fora(j, 0, m) {
            if (mas[i][j] == '.') {
                if (i > 0 && mas[i-1][j] == '.') {
                    nodes[i][j].edges.push_back(&nodes[i-1][j]);
                }
                if (j > 0 && mas[i][j-1] == '.') {
                    nodes[i][j].edges.push_back(&nodes[i][j-1]);
                }
                if (i+1 < n && mas[i+1][j] == '.') {
                    nodes[i][j].edges.push_back(&nodes[i+1][j]);
                }
                if (j+1 < m && mas[i][j+1] == '.') {
                    nodes[i][j].edges.push_back(&nodes[i][j+1]);
                }
                fora(ii, -2, 3) {
                    fora(jj, -2, 3) {
                        if (in(i+ii, j+jj) && mas[i+ii][j+jj] == '.') {
                            nodes[i][j].edges2.push_back(&nodes[i+ii][j+jj]);
                        }
                    }
                }
            }
        }
    }
    bfs(&nodes[a-1][b-1]);
//    fora(i, 0, n) {
//        fora(j, 0, m) {
//            cout << nodes[i][j].distance << " ";
//        }
//        cout << "\n";
//    }
    cout << (nodes[x-1][y-1].distance == 1000000000 ? -1 : nodes[x-1][y-1].distance);
    return 0;
}


Measured memory_bytes: 158688