#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <cassert>
#include <iomanip>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define rALL(a) (a).rbegin(), (a).rend()
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;

int x[4] = { -1,0,1,0 };
int y[4] = { 0,-1,0,1 }; 
vector<string> mp;
vector<vector<int>> dp;
int h, w;
int ch, cw, dh, dw;
void bfs(P start)
{
    //cout << "bfs : " << start.first << "," << start.second << "," << score << endl;
    queue<pair<P, int>> que2;
    pair<P, int> tmp;
    tmp.first = P(start.first, start.second);
    tmp.second = 0;
    que2.emplace(tmp);
    while (!que2.empty()) {
        pair<P, int> p2 = que2.front(); que2.pop();

        queue<P> que;
        que.push(P(p2.first.first, p2.first.second));
        vector<P> path;
        if (dp[p2.first.second][p2.first.first] <= p2.second) continue;
        dp[p2.first.second][p2.first.first] = p2.second;
        while (!que.empty()) {
            P p = que.front(); que.pop();
            path.emplace_back(p);
            //cout << p.first << "," << p.second << endl;
            rep(i, 4) {
                if (p.second + y[i] < 0 || h <= p.second + y[i]) continue;
                if (p.first + x[i] < 0 || w <= p.first + x[i]) continue;
                if (dp[p.second + y[i]][p.first + x[i]] != iINF) continue;
                if (mp[p.second + y[i]][p.first + x[i]] == '#') continue;
                dp[p.second + y[i]][p.first + x[i]] = dp[p.second][p.first];
                que.push(P(p.first + x[i], p.second + y[i]));
            }
        }

        //cout << "bfs : " << p2.first.first << "," << p2.first.second << "," << p2.second << endl;
        //rep(i, h) {
        //    rep(j, w) {
        //        cout << dp[i][j] << ",";
        //    }
        //    cout << endl;
        //}
        //cout << endl;

        int s = path.size();
        for (P p : path) {
            for (int i = -2; i <= 2; ++i) {
                for (int j = -2; j <= 2; ++j) {
                    //cout << i << "," << j << endl;
                    if (p.second + i < 0 || h <= p.second + i) continue;
                    if (p.first + j < 0 || w <= p.first + j) continue;
                    if (mp[p.second + i][p.first + j] == '#') continue;
                    if (i == 0 && j == 0) continue;
                    if ((i == 0 && j == -1) || (i == -1 && j == 0) || (i == 0 && j == 1) || (i == 1 && j == 0)) continue;
                    if (dp[p.second + i][p.first + j] <= p2.second) continue;
                    pair<P, int> tmp2;
                    tmp2.first = P(p.first + j, p.second + i);
                    tmp2.second = p2.second + 1;
                    que2.push(tmp2);
                }
            }
        }
    }
    /*
    queue<P> que;
    que.push(P(start.first, start.second));
    vector<P> path;
    if (dp[start.second][start.first] <= score) return;
    dp[start.second][start.first] = score;
    while (!que.empty()) {
        P p = que.front();
        que.pop();
        path.emplace_back(p);
        //cout << p.first << "," << p.second << endl;
        rep(i, 4) {
            if (p.second + y[i] < 0 || h <= p.second + y[i]) continue;
            if (p.first + x[i] < 0 || w <= p.first + x[i]) continue;
            if (dp[p.second + y[i]][p.first + x[i]] != iINF) continue;
            if (mp[p.second + y[i]][p.first + x[i]] == '#') continue;
            dp[p.second + y[i]][p.first + x[i]] = dp[p.second][p.first];
            que.push(P(p.first + x[i], p.second + y[i]));
        }
    }
    //rep(i, h) {
    //    rep(j, w) {
    //        cout << dp[i][j] << ",";
    //    }
    //    cout << endl;
    //}
    //cout << endl;
    int s = path.size();
    for(P p : path) {
        for (int i = -2; i <= 2; ++i) {
            for (int j = -2; j <= 2; ++j) {
                //cout << i << "," << j << endl;
                if (p.second + i < 0 || h <= p.second + i) continue;
                if (p.first + j < 0 || w <= p.first + j) continue;
                if (mp[p.second + i][p.first + j] == '#') continue;
                if (i == 0 && j == 0) continue;
                if ((i == 0 && j == -1) || (i == -1 && j == 0) || (i == 0 && j == 1) || (i == 1 && j == 0)) continue;
                if (dp[p.second + i][p.first + j] > score) bfs(P(p.first + j, p.second + i), score + 1);
            }
        }
    }
    //cout << "finished" << endl;
    */
}
int main()
{
    /*int n, x, t; cin >> n >> x >> t;
    int ans = ceil(double(n) / x) * t;
    cout << ans << endl;
    */

    /*string n; cin >> n;
    int s = n.size();
    int num = 0;
    rep(i, s) {
        num += n[i] - '0';
    }
    if (num % 9 == 0) cout << "Yes" << endl;
    else cout << "No" << endl;
    */

    /*int n; cin >> n;
    ll mx = 0;
    ll ans = 0;
    rep(i, n) {
        ll a; cin >> a;
        mx = max(mx, a);
        if (a < mx) ans += mx - a;
    }
    cout << ans << endl;
    */

    cin >> h >> w;
    cin >> ch >> cw >> dh >> dw;
    ch--; cw--; dh--; dw--;
    mp.resize(h);
    rep(i, h) cin >> mp[i];
    dp.resize(h);
    rep(i,h) dp[i].assign(w, iINF);
    bfs(P(cw, ch));
    if (dp[dh][dw] == iINF) cout << -1 << endl;
    else cout << dp[dh][dw] << endl;
    return 0;
}

Measured memory_bytes: 9664