#include <bits/stdc++.h>

// isDebug?
#ifndef ONLINE_JUDGE
#define _DEBUG
#endif

// Function Macros:
#define rep(i, n) for(int(i) = 0; (i) < (n); (i)++)
#define all(v) (v).begin(), (v).end()
#define setpre(n) cout << fixed << setprecision(n)

// -* https://xn--kst.jp/blog/2019/08/29/cpp-comp/ *- Thx :)
// debug methods
// usage: debug(x,y);
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0, a1, a2, a3, a4, x, ...) x
#define debug_1(x1) cout << #x1 << ": " << x1 << endl
#define debug_2(x1, x2) cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << endl
#define debug_3(x1, x2, x3) cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": " << x3 << endl
#define debug_4(x1, x2, x3, x4) cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": " << x3 << ", " #x4 << ": " << x4 << endl
#define debug_5(x1, x2, x3, x4, x5) cout << #x1 << ": " << x1 << ", " #x2 << ": " << x2 << ", " #x3 << ": " << x3 << ", " #x4 << ": " << x4 << ", " #x5 << ": " << x5 << endl
#ifdef _DEBUG
#define debug(...)                                                        \
    cout << __FILE__ << ": " << __LINE__ << ": " << __func__ << " -> ";   \
    CHOOSE((__VA_ARGS__, debug_5, debug_4, debug_3, debug_2, debug_1, ~)) \
    (__VA_ARGS__)
#else
#define debug(...)
#endif

// namespace / type / class / struct - alias, def:
using namespace std;

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

struct edge {
    ll to, cost;
};
typedef pair<ll, ll> P;
struct graph {
    ll V, INF = (1ll << 30) - 1;
    vector<vector<edge>> G;
    vector<ll> d;

    graph(ll n) {
        init(n);
    }

    void init(ll n) {
        V = n;
        G.resize(V);
        d.resize(V);
        rep(i, V) {
            d[i] = INF;
        }
    }

    void add_edge(ll s, ll t, ll cost) {
        edge e;
        e.to = t, e.cost = cost;
        G[s].push_back(e);
    }

    void dijkstra(ll s) {
        rep(i, V) {
            d[i] = INF;
        }
        d[s] = 0;
        priority_queue<P, vector<P>, greater<P>> que;
        que.push(P(0, s));
        while(!que.empty()) {
            P p = que.top();
            que.pop();
            ll v = p.second;
            if(d[v] < p.first) continue;
            for(auto e : G[v]) {
                if(d[e.to] > d[v] + e.cost) {
                    d[e.to] = d[v] + e.cost;
                    que.push(P(d[e.to], e.to));
                }
            }
        }
    }
};

// Constants:
const int INF = (1ll << 30) - 1;  // approx 1.07e9
const ll INFLL = 1ll << 60;       // approx 1.15e18
const int MOD = 1e9 + 7;          // 998244353
const long double EPS = 1.0e-14;
const int FACN = 510000;

// Global Variables:
// ll fac[FACN], finv[FACN], inv[FACN];

// Prototype Declarations:
int gcd(int, int);
int lcm(int, int);
template <class T>
inline bool chmin(T&, T);
template <class T>
inline bool chmax(T&, T);

// ================ Main Loop ================
int main() {
    int h, w, ch, cw, dh, dw;
    cin >> h >> w >> ch >> cw >> dh >> dw;
    --ch;
    --cw;
    --dh;
    --dw;
    vector<string> s(h);

    rep(i, h) {
        cin >> s[i];
    }

    vector<vector<int>> ans(h, vector<int>(w));
    rep(i, h) {
        rep(j, w) {
            ans[i][j] = INF;
        }
    }

    ans[ch][cw] = 0;

    vector<vector<bool>> bt;
    rep(i, h) {
        vector<bool> bone;
        rep(j, w) {
            bone.push_back(s[i][j] == '.');
        }
        bt.push_back(bone);
    }

    // graph
    graph g(h * w);

    // move
    rep(i, h) {
        rep(j, w) {
            for(int di = -2; di <= 2; ++di) {
                for(int dj = -2; dj <= 2; ++dj) {
                    if(i + di < 0 || i + di >= h) {
                        continue;
                    }
                    if(j + dj < 0 || j + dj >= w) {
                        continue;
                    }
                    if(di == 0 && dj == 0) {
                        continue;
                    }
                    if(!bt[i + di][j + dj]) {
                        continue;
                    }

                    if(abs(di) + abs(dj) <= 1) {
                        // move A
                        g.add_edge(i * w + j, (i + di) * w + j + dj, 0);
                    } else {
                        // move B
                        g.add_edge(i * w + j, (i + di) * w + j + dj, 1);
                    }
                }
            }
        }
    }

    g.dijkstra(ch * w + cw);
    if(g.d[dh * w + dw] > h * w) {
        cout << -1 << endl;
    } else {
        cout << g.d[dh * w + dw] << endl;
    }
    return 0;
}
// ===========================================

// Functions:
// 最大公約数 O(log(min(a, b)))
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}
// 最小公倍数 O(log(min(a, b)))
int lcm(int a, int b) {
    return a * b / gcd(a, b);
}

template <class T>
inline bool chmin(T& a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T>
inline bool chmax(T& a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}


Measured memory_bytes: 304516