/*** author: yuji9511 ***/
#include <bits/stdc++.h>
using namespace std;
// using int = long long;
using lpair = pair<int, int>;
const int MOD = 1e9+7;
const int INF = 1e9;
#define rep(i,m,n) for(int i=(m);i<(n);i++)
#define rrep(i,m,n) for(int i=(m);i>=(n);i--)
#define printa(x,n) for(int i=0;i<n;i++){cout<<(x[i])<<" \n"[i==n-1];};
void print() {}
template <class H,class... T>
void print(H&& h, T&&... t){cout<<h<<" \n"[sizeof...(t)==0];print(forward<T>(t)...);}
struct UnionFind {
private:
    int N;
    vector<int> parent;
    vector<int> num;
    vector<int> diff_weight;

public:
    UnionFind(int n){
        N = n;
        rep(i,0,N) parent.push_back(i);
        rep(i,0,N) num.push_back(1);
        rep(i,0,N) diff_weight.push_back(0);
    }

    int root(int x){
        if(x == parent[x]){
            return x;
        }else{
            int r = root(parent[x]);
            diff_weight[x] += diff_weight[parent[x]];
            return parent[x] = r;
        }
    }

    void unite(int a, int b, int w = 0){
        w += weight(a); w -= weight(b);
        a = root(a); b = root(b);
        if(a == b) return;
        parent[b] = a;
        int sum = num[a] + num[b];
        num[a] = sum;
        num[b] = sum;
        diff_weight[b] = w;
    }

    bool same(int a, int b){ return root(a) == root(b);}
    
    int sz(int x){ return num[root(x)];}

    int weight(int x){
        root(x);
        return diff_weight[x];
    }

    int diff(int a, int b){
        return weight(b) - weight(a);
    }
};


int dist[1000010] = {};
typedef struct {
    int h;
    int w;
    int d;
} P;
vector<int> tree[1000010];

void solve(){ 
    int H,W;
    cin >> H >> W;
    int Ch, Dh,Cw,Dw;
    cin >> Ch >> Cw >> Dh >> Dw;
    string S[1010];
    rep(i,0,H) cin >> S[i];
    Ch--; Dh--; Cw--; Dw--;
    int dh[4] = {0,0,1,-1};
    int dw[4] = {1,-1,0,0};
    // queue<P> que;
    // que.push({Ch, Cw, 0});

    rep(i,0,H){
        rep(j,0,W){
            dist[i*W+j] = INF;
        }
    }
    UnionFind uf(H * W + 10);

    rep(i,0,H){
        rep(j,0,W){
            if(S[i][j] == '#') continue;
            rep(k,0,4){
                int hh = i + dh[k], ww = j + dw[k];
                if(hh >= 0 && hh < H && ww >= 0 && ww < W && S[hh][ww] == '.'){
                    uf.unite(i * W + j, hh * W + ww);
                }
            }
        }
    }
    rep(h,0,H){
        rep(w,0,W){
            if(S[h][w] == '#') continue;
            rep(i,-2,3){
                rep(j,-2,3){
                    if(i == 0 && j == 0) continue;
                    int hh = h + i, ww = w + j;
                    if(hh >= 0 && hh < H && ww >= 0 && ww < W && S[hh][ww] == '.'){
                        if(not uf.same(h * W + w, hh * W + ww)){
                            // print(h,w,hh,ww);
                            tree[uf.root(h * W + w)].push_back(uf.root(hh * W + ww));
                        }
                    }
                }
            }
        }
    }
    dist[uf.root(Ch * W + Cw)] = 0;
    queue<int> que;
    que.push(uf.root(Ch * W + Cw));
    while(not que.empty()){
        int p = que.front();
        que.pop();
        for(auto &e: tree[p]){
            // print(p,e);
            if(dist[e] == INF){
                dist[e] = dist[p] + 1;
                que.push(e);
            }
        }
    }
    // rep(i,0,H){
    //     rep(j,0,W){
    //         cout << dist[i*W+j] << " ";
    //     }
    //     cout << endl;
    // }
    if(dist[uf.root(Dh*W+Dw)] == INF){
        print(-1);
    }else{
        print(dist[uf.root(Dh*W+Dw)]);
    }



    // while(not que.empty()){
    //     P l1 = que.front();
    //     que.pop();
    //     int h = l1.h, w = l1.w;
    //     // print(h,w, dist[h][w], l1.d);
    //     if(dist[h][w] <= l1.d) continue;
    //     // if(dist[h][w] != INF) continue;
    //     dist[h][w] = l1.d;
    //     rep(k,0,4){
    //         int hh = h + dh[k];
    //         int ww = w + dw[k];
    //         if(dist[hh][ww] <= l1.d || S[hh][ww] == '#') continue;
    //         if(hh >= 0 && hh < H && ww >= 0 && ww < W){
    //             que.push({hh, ww, l1.d});
    //         }
    //     }
    //     rep(i,-2,3){
    //         rep(j,-2,3){
    //             if(i == 0 && j == 0) continue;
    //             int hh = h + i;
    //             int ww = w + j;
    //             if(dist[hh][ww] <= l1.d+1 || S[hh][ww] == '#') continue;
    //             if(hh >= 0 && hh < H && ww >= 0 && ww < W){
    //                 que.push({hh, ww, l1.d + 1});
    //             }

    //         }
    //     }
    // }
    // if(dist[Dh][Dw] == INF){
    //     print(-1);
    // }else{
    //     print(dist[Dh][Dw]);
    // }

}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
}


Measured memory_bytes: 54972