#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
// #define INF 1e9
#define ALL(v) v.begin(), v.end()
using namespace std;
typedef long long ll;

struct Edge
{
    long long to;
    long long cost;
};
using Graph = vector<vector<Edge>>;
using P = pair<long, int>;
const long long INF = 1LL << 60;

/* dijkstra(G,s,dis)
    入力：グラフ G, 開始点 s, 距離を格納する dis
    計算量：O(|E|log|V|)
    副作用：dis が書き換えられる
*/
void dijkstra(const Graph &G, int s, vector<long long> &dis)
{
    int N = G.size();
    dis.resize(N, INF);
    priority_queue<P, vector<P>, greater<P>> pq; // 「仮の最短距離, 頂点」が小さい順に並ぶ
    dis[s] = 0;
    pq.emplace(dis[s], s);
    while (!pq.empty())
    {
        P p = pq.top();
        pq.pop();
        int v = p.second;
        if (dis[v] < p.first)
        { // 最短距離で無ければ無視
            continue;
        }
        for (auto &e : G[v])
        {
            if (dis[e.to] > dis[v] + e.cost)
            { // 最短距離候補なら priority_queue に追加
                dis[e.to] = dis[v] + e.cost;
                pq.emplace(dis[e.to], e.to);
            }
        }
    }
}

int main()
{
    ll H, W;
    cin >> H >> W;
    ll Ch, Cw, Dh, Dw;
    cin >> Ch >> Cw >> Dh >> Dw;
    Ch--;
    Cw--;
    Dh--;
    Dw--;
    vector<vector<ll>> mat(H, vector<ll>(W, 0));
    REP(i, H) {
        string s;
        cin >> s;
        REP(j, W) {
            if (s[j] == '#')
                mat[i][j] = -1;
        }
    }
    ll cnt = 1;
    REP(i, H)
    {
        REP(j, W)
        {
            if (mat[i][j] != 0)
                continue;
            queue<ll> q;
            q.push(i * W + j);
            while (!q.empty())
            {
                ll t = q.front();
                q.pop();

                ll i = t / W;
                ll j = t % W;
                FOR(k, -1, 2)
                {
                    FOR(l, -1, 2)
                    {
                        if (!(k == 0 || l == 0))
                            continue;
                        ll x = i + k;
                        ll y = j + l;
                        if (0 <= x && x < H && 0 <= y && y < W)
                        {
                            if (mat[x][y] == 0) {
                                mat[x][y] = cnt;
                                q.push(x * W + y);
                            }
                        }
                    }
                }
            }
            cnt++;
        }
    }
    // REP(i, H) {
    //     REP(j, W) {
    //         cout << mat[i][j] << " ";
    //     }
    //     cout << endl;
    // }
    
    Graph g = vector<vector<Edge>>(H*W, vector<Edge>());
    REP(i, H) {
        REP(j, W) {
            if (mat[i][j] == -1)
                continue;
            FOR(k, -2, 3) {
                FOR(l, -2, 3) {
                    ll x = i + k;
                    ll y = j + l;
                    if (0 <= x && x < H && 0 <= y && y < W) {
                        if (mat[x][y] == -1)
                            continue;
                        Edge e;
                        e.to = x * W + y;
                        if (mat[x][y] != mat[i][j]) {
                            e.cost = 1;
                        } else {
                            e.cost = 0;
                        }
                        g[i * W + j].push_back(e);
                    }
                }
            }
        }
    }
    // REP(i, H*W) {
    //     cout << i << endl;
    //     for (auto e : g[i]) {
    //         cout << e.to << " : " << e.cost << endl;
    //     }
    //     cout << endl;
    // }
    vector<long long> dis = vector<long long>(H * W, INF);
    dijkstra(g, Ch * W + Cw, dis);
    if (dis[Dh*W+Dw] == INF) {
        cout << -1 << endl;
    } else {
        cout << dis[Dh * W + Dw] << endl;
    }
    
}


Measured memory_bytes: 182540