//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <climits>
//#define DBG

using namespace std;
using ll = long long;
int H, W;
int Ch, Cw, Dh, Dw;
char b[1000][1000];
ll memo[1000][1000];
vector<ll> A;

struct Corr {
    ll y;
    ll x;
    ll warpcnt;
    Corr(ll in_y, ll in_x){
        warpcnt = 0;
        y = in_y;
        x = in_x;
    }
    Corr(ll in_y, ll in_x, ll in_warpcnt){
        warpcnt = in_warpcnt;
        y = in_y;
        x = in_x;
    }
    bool operator <(const Corr& rhs) const{
        return (y==rhs.y) ? ((x == rhs.x) ? warpcnt < rhs.warpcnt : x < rhs.x) : y < rhs.y;
    }
};

void printboard(){
        for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            cout << memo[i][j] << ',' << flush;
        }
        cout << endl;
    }

}

ll minwarp = LLONG_MAX;

int main(){
    cin >> H >> W;
    cin.ignore();
    cin >> Ch >> Cw;
    --Ch;
    --Cw;
    cin.ignore();
    cin >> Dh >> Dw;
    --Dh;
    --Dw;
    cin.ignore();
 
    for(int i = 0; i < 1000; i++){
        for(int j = 0; j < 1000; j++){
            memo[i][j] = LLONG_MAX;
        }
    }
 
    for(int i = 0; i < H; i++){
        string s;
        cin >> s;
        for(int j = 0; j < W; j++){
            b[i][j] = s[j];
        }
        cin.ignore();
    }
 
    queue<Corr> q;
    q.push(Corr(Ch, Cw));

    ll lcnt = 0;
    while(!q.empty()){
        vector<Corr> st;
        while(!q.empty()){
            Corr now = q.front();
            q.pop();
            // マスにスコアつけ
            if(memo[now.y][now.x] < now.warpcnt && memo[now.y][now.x] != LLONG_MAX) continue; // コスト大or訪問済みなら省略
            memo[now.y][now.x] = now.warpcnt;
            st.push_back(now);
            if(now.y == Dh && now.x == Dw) continue; // 目的地なら終了
            // -Y
            if(now.y > 0){
                if(b[now.y - 1][now.x] == '.' && (memo[now.y - 1][now.x] > now.warpcnt)){
                    memo[now.y - 1][now.x] = now.warpcnt;
                    q.push(Corr(now.y - 1, now.x, now.warpcnt));
                }
            }
            // -X
            if(now.x > 0){
                if(b[now.y][now.x - 1] == '.' && memo[now.y][now.x - 1] > now.warpcnt){
                    memo[now.y][now.x - 1] = now.warpcnt;
                    q.push(Corr(now.y, now.x - 1, now.warpcnt));
                }
            }
            // +Y
            if(now.y < H - 1){
                if(b[now.y + 1][now.x] == '.' && memo[now.y + 1][now.x] > now.warpcnt){
                    memo[now.y + 1][now.x] = now.warpcnt;
                    q.push(Corr(now.y + 1, now.x, now.warpcnt));
                }
            }
            // +X
            if(now.x < W - 1){
                if(b[now.y][now.x + 1] == '.' && memo[now.y][now.x + 1] > now.warpcnt){
                    memo[now.y][now.x + 1] = now.warpcnt;
                    q.push(Corr(now.y, now.x + 1, now.warpcnt));
                }
            }
        }

        for(const Corr& c : st){
            ll up_X = (c.x + 2 >= W) ? W : c.x + 2;
            ll up_Y = (c.y + 2 >= H) ? H : c.y + 2;
            ll low_X = (c.x - 2 <= 0) ? 0 : c.x - 2;
            ll low_Y = (c.y - 2 <= 0) ? 0 : c.y - 2;
            for(ll i = low_Y; i <= up_Y; i++){
                for(ll j = low_X; j <= up_X; j++){
                    if(memo[i][j] > lcnt + 1 && b[i][j] == '.'){
                        q.push(Corr(i, j, lcnt + 1));
                        memo[i][j] = lcnt + 1;
                    }
                }
            }
        }
        ++lcnt;
    }

    if(memo[Dh][Dw] == LLONG_MAX){
        cout << -1 << endl;
    } else {
        cout << memo[Dh][Dw] << endl;
    }
 
#ifdef DBG
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            cout << memo[i][j] << ',' << flush;
        }
        cout << endl;
    }
#endif
    
    return 0;
}

Measured memory_bytes: 12824