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

int H, W;
vector<vector<char> > maze;
vector<vector<bool> > seen;
vector<vector<int> > dist;
queue<pair<int, int> > walked;

void walk(int h, int w, int n)
{
    seen[h][w] = true;
    queue<pair<int, int> > que;
    pair<int, int> start;
    start.first = h;
    start.second = w;
    que.push(start);
    while(!que.empty())
    {
        pair<int, int> nowon = que.front();
        que.pop();
        walked.push(nowon);
        dist[nowon.first][nowon.second] = n;
        for (int i=-1; i<=1; i+=2)
        {
            if (nowon.first+i>=0 && nowon.first+i<H)
            {
                if (!seen[nowon.first+i][nowon.second] && maze[nowon.first+i][nowon.second]=='.')
                {
                    pair<int, int> next;
                    next.first = nowon.first + i;
                    next.second = nowon.second;
                    que.push(next);
                    seen[next.first][next.second] = true;
                }
            }
        }
        for (int i=-1; i<=1; i+=2)
        {
            if (nowon.second+i>=0 && nowon.second+i<W)
            {
                if (!seen[nowon.first][nowon.second+i] && maze[nowon.first][nowon.second+i]=='.')
                {
                    pair<int, int> next;
                    next.first = nowon.first;
                    next.second = nowon.second+i;
                    que.push(next);
                    seen[next.first][next.second] = true;
                }
            }
        }
    }
}

int main()
{
    //入力受け取り
    // ---------------------------------------------
    cin >> H >> W;
    pair<int, int> start;
    cin >> start.first >> start.second;
    pair<int, int> goal;
    cin >> goal.first >> goal.second;
    start.first--;
    start.second--;
    goal.first--;
    goal.second--;
    //配列初期化
    maze = vector<vector<char> >(H, vector<char>(W));
    seen = vector<vector<bool> >(H, vector<bool>(W, false));
    dist = vector<vector<int> > (H, vector<int>(W, -1));
    for (int i=0; i<H; i++)
    {
        for (int j=0; j<W; j++) cin >> maze[i][j];
    }
    //cout << "hey" << endl;
    // ---------------------------------------------
    //処理
    //1. スタートから歩ける場所を列挙
    //2. 歩いた場所からワープできる場所を列挙
    //3. ワープ先から歩ける場所を列挙　以下ループ
    int warp_num=0;
    queue<pair<int, int> > warp_to;
    warp_to.push(start);
    while (true)
    {
        while (!warp_to.empty())
        {
            pair<int, int> v = warp_to.front();
            warp_to.pop();
            if (!seen[v.first][v.second] && maze[v.first][v.second]=='.') walk(v.first, v.second, warp_num);
        }

        while (!walked.empty())
        {
            pair<int, int> v = walked.front();
            walked.pop();
            for (int i=-2; i<=2; i++)
            {
                for (int j=-2; j<=2; j++)
                {
                    if (v.first+i>=0 && v.first+i<H && v.second+j>=0 && v.second+j<W)
                    {
                        if (!seen[v.first+i][v.second+j] && maze[v.first+i][v.second+j]=='.')
                        {
                            pair<int, int> w;
                            w.first = v.first+i;
                            w.second = v.second+j;
                            warp_to.push(w);
                        }
                    }
                }
            }
        }
        warp_num++;
        if (warp_to.empty()) break;
    }
    
    // デバッグ用：全体図を出力
    // ---------------------------------------------
    /*
    for (int i=0; i<H; i++)
    {
        for (int j=0; j<W; j++)
        {
            cout << dist[i][j] << " ";
        }
        cout << endl;
    }
    */
    // ---------------------------------------------

    cout << dist[goal.first][goal.second] << endl;
}

Measured memory_bytes: 8792