#include <bits/stdc++.h>
using namespace std;

using P = pair<int, int>;

const int MAX_V = 500 * 500;
const int INF = 1e8;

struct edge
{
    int to, cost;
};
typedef pair<int, int> P; // first は最短距離、 second は頂点の番号

int V;
vector<edge> G[MAX_V];
int d[MAX_V];

void dijkstra(int s)
{
    // greater<P> を指定することで first が小さい順に取り出せるようにする
    priority_queue<P, vector<P>, greater<P>> que;
    fill(d, d + V, INF);
    d[s] = 0;
    que.push(P(0, s));
    while (!que.empty())
    {
        P p = que.top();
        que.pop();
        int v = p.second;
        if (d[v] < p.first)
            continue;
        for (int i = 0; i < G[v].size(); i++)
        {
            edge e = G[v][i];
            if (d[e.to] > d[v] + e.cost)
            {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
}

vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, 1, 0, -1};

void fill(int y, int x, int cur, vector<vector<int>> &T)
{
    T[y][x] = cur;
    for (int i = 0; i < 4; i++)
    {
        int ny = y + dy[i];
        int nx = x + dx[i];
        if (T[ny][nx] == -1)
        {
            fill(ny, nx, cur, T);
        }
    }
}

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
int main()
{
    // Failed to predict input format
    int H, W, Ch, Cw, Dh, Dw;
    cin >> H >> W >> Ch >> Cw >> Dh >> Dw;
    vector<string> S(H + 2);
    S[0] = string(W + 2, '#');
    S[H + 1] = string(W + 2, '#');
    for (int i = 1; i <= H; i++)
    {
        cin >> S[i];
        S[i] = "#" + S[i] + "#";
    }

    vector<vector<int>> T(H + 2, vector<int>(W + 2));
    for (int i = 1; i <= H; i++)
    {
        for (int j = 1; j <= W; j++)
        {
            if (S[i][j] == '.')
            {
                T[i][j] = -1;
            }
        }
    }

    // for (int i = 0; i <= H + 1; i++) {
    //     cout << S[i] << endl;
    // }
    // cout << endl;

    int cur = 1;
    for (int i = 1; i <= H; i++)
    {
        for (int j = 1; j <= W; j++)
        {
            if (T[i][j] == -1)
            {
                fill(i, j, cur, T);
                cur++;
            }
        }
    }

    // int d[cur + 1][cur + 1];
    // memset(d, 0x3f, sizeof(d));

    // vector<edge> es;
    set<P> seen;
    for (int i = 1; i <= H; i++)
    {
        for (int j = 1; j <= W; j++)
        {
            int u = T[i][j];
            if (u == 0)
            {
                continue;
            }
            for (int dy = -2; dy <= 2; dy++)
            {
                for (int dx = -2; dx <= 2; dx++)
                {
                    int ny = i + dy;
                    int nx = j + dx;
                    if (ny <= 0 || ny > H || nx <= 0 || nx > W)
                    {
                        continue;
                    }
                    int v = T[ny][nx];
                    if (v == 0)
                    {
                        continue;
                    }

                    // if (u == v) {
                    //     d[u][v] = 0;
                    // } else {
                    //     d[u][v] = d[v][u] = 1;
                    // }
                    if (seen.count(P(u, v)))
                    {
                        continue;
                    }
                    if (u == v)
                    {
                        continue;
                    }
                    G[u].push_back({v, 1});
                    G[v].push_back({u, 1});
                    seen.insert(P(u, v));
                    seen.insert(P(v, u));
                }
            }
        }
    }

    V = cur;
    dijkstra(T[Ch][Cw]);
    int ans = d[T[Dh][Dw]];
    if (ans == INF)
    {
        cout << -1 << endl;
    }
    else
    {
        cout << ans << endl;
    }

    // for (int i = 1; i <= H; i++) {
    //     for (int j = 1; j <= W; j++) {
    //         printf("%c", T[i][j] + 0x20);
    //     }
    //     printf("\n");
    // }

    // for (int i = 0; i < cur+1; i++) {
    //     for (int j = 0; j < cur+1; j++) {
    //         printf("%10d ", d[i][j]);
    //     }
    //     printf("\n");
    // }

    // int V = cur + 1; //  頂点数
    // for (int k = 0; k < V; k++) {
    //     for (int i = 0; i < V; i++) {
    //         for (int j = 0; j < V; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    //     }
    // }

    // cout << T[Ch][Cw] << ", " << T[Dh][Dw] << endl;
    // for (int i = 0; i < cur+1; i++) {
    //     for (int j = 0; j < cur+1; j++) {
    //         printf("%9d ", d[i][j]);
    //     }
    //     printf("\n");
    // }

    // int ans = d[T[Ch][Cw]][T[Dh][Dw]];
    // if (ans == 0x3f3f3f3f) {
    //     cout << -1 << endl;
    // } else {
    //     cout << ans << endl;
    // }
}


Measured memory_bytes: 40196