#include<iostream>
#include<cmath>
#include<vector>
#include<deque>
using namespace std;

int judge_ikeru(int h, int w, int max_h, int max_w);

int main(){
    int H, W;
    int Sh, Sw;
    int Gh, Gw;
    char cell;
    int now_h, now_w;
    int judge;
    long long count = 0;
    vector<int> temp_v(4), now_v(4);
    deque<vector<int>> q_maze;
   
    std::cin >> H >> W >> Sh >> Sw >> Gh >> Gw;
    Sh = Sh -1;
    Sw = Sw -1;
    Gh = Gh -1;
    Gw = Gw -1;
    int ans = -1;

    now_h = Sh;
    now_w = Sw;



    vector<vector<int>> maze;
    vector<int> v(W);

    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            std::cin >> cell;
            if(cell == '#'){
                //# = 1は壁
                v[j] = 1;
            }else{
                v[j] = 0;
            }
        }
        maze.push_back(v);
    }
    //ここまでインプット

    //最初だけ
    temp_v = {now_h, now_w, 0, 0};
    q_maze.push_front(temp_v);
    maze[now_h][now_w] = 1;

    while(q_maze.size() != 0){
        //左の状態を取得
        now_v = q_maze[0];
        q_maze.pop_front();
        //goal判定
        if(now_v[0] == Gh && now_v[1] == Gw){
            if(now_v[3] > ans){
                ans = now_v[3];
                break;
            }
        }else if(now_v[2] == 1 && maze[now_v[0]][now_v[1]] == 1){
            //テレポで来たけど既にコス0で来られていた場合何もしない
            // std::cout << "bug" << now_h << " " << now_w << " " << maze[now_h][now_w] << "\n";
        }else{
            //ゴールに行ったら派生しない
            now_h = now_v[0];
            now_w = now_v[1];

            for(int i = -2; i <= 2; i++){
                for(int j = -2; j <= 2; j++){
                    if(i != 0 || j !=0){
                        //自分の立ち位置はさすがにだめ
                        judge = judge_ikeru(now_h + i, now_w + j, H - 1, W - 1);
                        if(judge == 1){
                            //端っこじゃなければさらに判定
                            if(labs((long long)i) + labs((long long)j) == 1){
                                //コス0移動の場合
                                if(maze[now_h + i][now_w + j] != 1){
                                    maze[now_h + i][now_w + j] = 1;
                                    temp_v = {now_h + i, now_w + j, 0, now_v[3]};
                                    q_maze.push_front(temp_v);
                                }
                            }else{
                                //テレポ移動の場合
                                if(maze[now_h + i][now_w + j] == 0){
                                    maze[now_h + i][now_w + j] = 2;
                                    temp_v = {now_h + i, now_w + j, 1, now_v[3] + 1};
                                    q_maze.push_back(temp_v);
                                }                                
                            }
                        }

                    }
                }
            }

            count++;         
        }

        if(count > W * H){
            break;
        }
    }

    if(ans == W * H){
        std::cout << -1;
    }else{
        std::cout << ans;
    }

    
}

int judge_ikeru(int h, int w, int max_h, int max_w){
    int ans = 1;

    if(h < 0 || h > max_h || w < 0 || w > max_w){
        ans = 0;
    }
    return ans;
}

Measured memory_bytes: 8160