#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int INF = 1001001001;
const ll LINF = 1LL << 60;
const int MOD = 1'000'000'007;

template <typename T>
void print(const T &v)
{
    for (int i = 0; i < v.size(); i++)
    {
        if (i)
            cout << ' ';
        cout << v[i];
    }
    cout << endl;
}

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;
}

int main()
{
    int h, w, ch, cw, dh, dw;
    cin >> h >> w >> ch >> cw >> dh >> dw;
    --ch;
    --cw;
    --dh;
    --dw;
    vector<vector<char>> grid(h, vector<char>(w));
    for (int i = 0; i < h; i++)
    {
        for (int j = 0; j < w; j++)
        {
            cin >> grid[i][j];
        }
    }
    vector<vector<int>> score(h, vector<int>(w, INF));
    score[ch][cw] = 0;
    //
    queue<P> stop_list;
    set<P> stop_check;
    //
    queue<P> start_list;
    set<P> start_check;
    //
    start_list.push(make_pair(ch, cw));
    start_check.insert(make_pair(ch, cw));

    while (!start_list.empty())
    {
        P start = start_list.front();
        start_list.pop();
        queue<P> qe;
        qe.push(start);
        // 幅優先探索で連続空間を網羅する
        while (!qe.empty())
        {
            P now = qe.front();
            qe.pop();
            int x = now.first;
            int y = now.second;
            int xs[4] = {1, -1, 0, 0};
            int ys[4] = {0, 0, 1, -1};
            for (int i = 0; i < 4; i++)
            {
                int nx = x + xs[i];
                int ny = y + ys[i];
                // 範囲内確認
                if (nx < 0 || ny < 0 || nx >= h || ny >= w)
                {
                    continue;
                }
                // 壁かどうかを確認
                if (grid[nx][ny] == '#')
                {
                    if (!stop_check.count(make_pair(x, y)))
                    {
                        stop_list.push(make_pair(x, y));
                        stop_check.insert(make_pair(x, y));
                    }
                    continue;
                }
                // 既に探索済かを確認する
                if (score[nx][ny] <= score[x][y])
                {
                    continue;
                }
                score[nx][ny] = min(score[nx][ny], score[x][y]);
                qe.push(make_pair(nx, ny));
            }
        }
        // 魔法で未到達箇所に移動できるか確認する
        while (!stop_list.empty())
        {
            P now = stop_list.front();
            stop_list.pop();
            int x = now.first;
            int y = now.second;
            int xs[20] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2};
            int ys[20] = {-2, -1, 0, 1, 2, -2, -1, 1, 2, -2, 2, -2, -1, 1, 2, -2, -1, 0, 1, 2};
            for (int i = 0; i < 20; i++)
            {
                int nx = x + xs[i];
                int ny = y + ys[i];
                // 範囲内確認
                if (nx < 0 || ny < 0 || nx >= h || ny >= w)
                {
                    continue;
                }
                // 壁かを確認
                if (grid[nx][ny] == '#')
                {
                    continue;
                }
                // 訪問済かを確認
                if (score[nx][ny] != INF)
                {
                    continue;
                }
                if (!start_check.count(make_pair(nx, ny)))
                {
                    score[nx][ny] = min(score[nx][ny], score[x][y] + 1);
                    start_list.push(make_pair(nx, ny));
                    start_check.insert(make_pair(nx, ny));
                }
            }
        }
    }
    if (score[dh][dw] == INF)
    {
        cout << -1 << endl;
    }
    else
    {
        cout << score[dh][dw] << endl;
    }
    return 0;
}


Measured memory_bytes: 42924