#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
typedef long long ll;
using namespace std;
using namespace __gnu_pbds;
#define lcnt (cnt<<1)
#define rcnt (cnt<<1|1)
#define vt vector
#define pb push_back
#define all(c) (c).begin(), (c).end()
#define sz(x) (int)(x).size()
#define F_OR(i, a, b, s) for (int i=(a); (s)>0?i<(b):i>(b); i+=(s))
#define F_OR1(e) F_OR(i, 0, e, 1)
#define F_OR2(i, e) F_OR(i, 0, e, 1)
#define F_OR3(i, b, e) F_OR(i, b, e, 1)
#define F_OR4(i, b, e, s) F_OR(i, b, e, s)
#define GET5(a, b, c, d, e, ...) e
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
#define EACH(x, a) for (auto& x: a)
template<class T> bool umin(T& a, const T& b) {return b<a?a=b, 1:0;}
template<class T> bool umax(T& a, const T& b) {return a<b?a=b, 1:0;}
ll FIRSTTRUE(function<bool(ll)> f, ll lb, ll rb) {
    while(lb<rb) {
        ll mb=(lb+rb)/2;
        f(mb)?rb=mb:lb=mb+1;
    }
    return lb;
}
ll LASTTRUE(function<bool(ll)> f, ll lb, ll rb) {
    while(lb<rb) {
        ll mb=(lb+rb+1)/2;
        f(mb)?lb=mb:rb=mb-1;
    }
    return lb;
}

template<class A> void read(vt<A>& v);
template<class A, size_t S> void read(array<A, S>& a);
template<class H, class T> void read(pair<H,T>&c);
template<class T> void read(T& x) {cin >> x;}
void read(double& d) {
    string t;
    read(t);
    d=stod(t);
}
void read(long double& d) {
    string t;
    read(t);
    d=stold(t);
}
template<class H, class T> void read(pair<H,T>&c){read(c.first);read(c.second);}
template<class H, class... T> void read(H& h, T&... t) {read(h);read(t...);}
template<class A> void read(vector<A>& x) {EACH(a, x)read(a);}
template<class A, size_t S> void read(array<A, S>& x) {EACH(a, x)read(a);}
string to_string(char c) {return string(1, c);}
string to_string(bool b) {return b?"true":"false";}
string to_string(const char* s) {return string(s);}
string to_string(string s) {return s;}
string to_string(vector<bool> v) {
    string res;
    FOR(sz(v))res+=char('0'+v[i]);
    return res;
}
template<class T,class U> string to_string(pair<T,U> a){
    return to_string(a.first)+":"+to_string(a.second);
}
template<size_t S> string to_string(bitset<S> b) {
    string res;
    FOR(S)res+=char('0'+b[i]);
    return res;
}

template <class T> string to_string(T v) {
    char c=' ';
    if constexpr (std::is_same_v<T, vector<vector<ll>>>) c='\n';
    if constexpr (std::is_same_v<T, vector<vector<int>>>) c='\n';
    bool f=1;
    string res;
    EACH(x, v) {
        if(!f)res+=c;
        f=0;
        res+=to_string(x);
    }
    return res;
}
template<class A> void write(A x) {cout << to_string(x);}
template<class H, class... T> void write(const H& h, const T&... t) {write(h);write(t...);}
template<class H, class... T> void print(const H& h, const T&... t);
void print() {write("\n");}
template<class H, class... T> void print(const H& h, const T&... t) {
    write(h);
    if(sizeof...(t))write(' ');
    print(t...);
}
void DBG() {cout << "]" << endl;}
template<class H, class... T> void DBG(H h, T... t) {
    cout << to_string(h);
    if(sizeof...(t))
        cout << ", ";
    DBG(t...);
}
#define _DEBUG
#ifdef _DEBUG
#define debug(...) cout << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [\n", DBG(__VA_ARGS__)
#else
#define debug(...) 0
#endif

template<class T> void offset(ll o, T& x) {x+=o;}
template<class T> void offset(ll o, vt<T>& x) {
    EACH(a, x)offset(o, a);
}
template<class T, size_t S> void offset(ll o, array<T, S>& x) {
    EACH(a, x)offset(o, a);
}

mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());
ll randint(ll a, ll b) {
    return uniform_int_distribution<ll>(a, b)(mt_rng);
}
template<class T, class U> void vti(vt<T> &v, U x, size_t n) {v=vt<T>(n, x);}
template<class T, class U> void vti(vt<T> &v, U x, size_t n, size_t m...) {
    v=vt<T>(n);
    EACH(a, v)vti(a, x, m);
}
int dir[]={1,0,0,1,-1,0,0,-1};
const int MAXN = 1e3+20;
const int LOGMAXN = 18;
ll const MOD=1e9+7;
int n,m;
vector<string>vec;
vector<vector<int>>num;
void dfs(vector<int>c,vector<vector<int>>&curarea){
    curarea.push_back(c);
    FOR(4){
        int ny=c[0]+dir[i*2],nx=c[1]+dir[i*2+1];
        if(ny>=0 && nx >=0 && nx<m && ny<n && vec[ny][nx]=='.' && num[ny][nx]==-1){
            num[ny][nx]=num[c[0]][c[1]];
            dfs({ny,nx},curarea);
        }
    }
}
void solve() {
    read(n,m);
    vec=vector<string>(n);
    vector<int>aa(2),bb(2);
    vti(num,-1,n,m);
    read(aa,bb,vec);
    FOR(2)aa[i]--;
    FOR(2)bb[i]--;
    num[aa[0]][aa[1]]=0;
    queue<vector<int>>q;
    q.push(aa);
    while(!q.empty()){
        vector<vector<int>>st;
        vector<vector<int>>curarea;
        while(!q.empty()){
            st.push_back(q.front());
            q.pop();
        }
        for (auto c:st)dfs(c,curarea);
//        debug(num);
//        debug(curarea);
        for (auto c:curarea){
            FOR(dy,-2,3)FOR(dx,-2,3){
                int ny=c[0]+dy,nx=c[1]+dx;
                //debug(vector<int>{ny,nx});
                if(ny>=0 && nx >=0 && nx<m && ny<n && vec[ny][nx]=='.' && num[ny][nx]==-1){
                    num[ny][nx]=num[c[0]][c[1]]+1;
                    q.push({ny,nx});
                }
            }
        }
    }
    print(num[bb[0]][bb[1]]);
}
int main() {
//    ios::sync_with_stdio(false);
//    cin.tie(nullptr);
    int t=1;
    //read(t);
    FOR(t) {
        //write("Case #", i+1, ": ");
        solve();
    }
    return 0;
}
/*
99
2
1 2
1
5

2
1 2
3
2 3 5


10
2 3 4 5 6 7 1 6 4 2
ans:6

11
2 3 4 5 6 7 1 6 4 2 1
ans:7

11

ans:7

12
2 3 4 5 6 7 1 6 4 2 12 11
ans:7

17
2 3 4 5 6 7 1 6 4 2 13 13 14 15 16 14 14
ans:10



5
2 1 1 5 4
6
2 1 4 3 6 5
6
2 3 1 5 6 4
8
2 3 4 2 6 7 8 6
10
2 3 4 5 2 7 8 9 10 7

 * */

Measured memory_bytes: 10336