#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

// H×Wの迷路，(sx, sy)から歩いて移動できる所のワープ回数をqueueで求める まだ行ったことのないtimeは-1
//que_warpはwalkで値が更新される座標を保持するqueue
void walk (int H, int W, int sx, int sy, vector<vector<char>> &maze, vector<vector<int>> &time, queue<P> &que_warp) {
    vector<int> dx = {-1, 1, 0, 0};
    vector<int> dy = {0, 0, -1, 1};

    queue<P> que;
    que.push(P (sx, sy));

    while (que.size() > 0) {
        P p = que.front();
        que.pop();
        for (int i = 0; i < 4; i++) {
            int nx = p.first + dx[i];
            int ny = p.second + dy[i];
            if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' && time[nx][ny] == -1) {
                time[nx][ny] = time[p.first][p.second];
                que.push(P (nx, ny));
                que_warp.push(P (nx, ny));
            }
        }
    }
    return;
}

// (sx, sy)からワープで移動できるところのワープ回数を求める
void warp (int H, int W, int sx, int sy, vector<vector<char>> &maze, vector<vector<int>> &time, queue<P> &que_walk) {
    for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
            int nx = sx + i;
            int ny = sy + j;
            if (nx > 0 && nx <= H && ny > 0 && ny <= W && maze[nx][ny] == '.' && time[nx][ny] == -1) {
                time[nx][ny] = time[sx][sy] + 1;
                que_walk.push(P (nx, ny));
            }
        }
     }
    return;
}



int main () {
    int H, W, sx, sy, gx, gy; //sはスタート，gはゴール
    cin >> H >> W >> sx >> sy >> gx >> gy;
    
    vector<vector<char>> maze(H + 1, vector<char> (W + 1));
    for (int i = 1; i <= H; i++) {
        string s;
        cin >> s;
        for (int j = 1; j <= W; j++) {
            maze[i][j] = s[j - 1];
        }
    }

    vector<vector<int>> time(H + 1, vector<int> (W + 1, -1));
    
    time[sx][sy] = 0;
    
    queue<P> que_walk;
    que_walk.push(P (sx, sy));

    queue<P> que_warp; //ワープで始点となる座標を入れるqueue

    /* walk (H, W, sx, sy, maze, time, que_warp);
    while (que_warp.size() > 0) {
        P p =que_warp.front();
        que_warp.pop();
        warp (H, W, p.first, p.second, maze, time, que_walk);
    }
    cout << "que_walk:" << endl;
    while (que_walk.size() > 0) {
        
        P p = que_walk.front();
        que_walk.pop();
        cout << p.first << " " << p.second << endl;  
    }
    cout << "que_warp:" << endl;
    while (que_warp.size() > 0) {
        cout << "que_warp:" << endl;
        P p = que_warp.front();
        que_warp.pop();
        cout << p.first << " " << p.second << endl;
    }
    cout << "time:" << endl;
    for (int i = 1; i <= H; i++) {
        for (int j = 1; j <= W; j++){
            cout << setw(3) << time[i][j];
        }
        cout << endl;
    } */


    while (que_walk.size() > 0) {
        if (time[gx][gy] != -1) {
            break;
        }
        
        while (que_walk.size() > 0) {
            P p = que_walk.front();
            que_walk.pop();
            que_warp.push(P (p.first, p.second));
            walk (H, W, p.first, p.second, maze, time, que_warp);
        }

        while (que_warp.size() > 0) {
            P p = que_warp.front();
            que_warp.pop();
            warp (H, W, p.first, p.second, maze, time, que_walk);
        }
    }

    /*
    cout << "time:" << endl;
    for (int i = 1; i <= H; i++) {
        for (int j = 1; j <= W; j++){
            cout << setw(3) << time[i][j];
        }
        cout << endl;
    }*/

    cout << time[gx][gy] << endl; 
}

Measured memory_bytes: 8720