#include<bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
 
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
 
#define start_routine() int begtime = clock();
#define end_routine() int endtime = clock(); cerr << endl << "Time elapsed: " << (endtime - begtime)*1000/CLOCKS_PER_SEC << " ms"; return 0
#define speed() cin.tie(0), cout.tie(0), ios_base::sync_with_stdio(false)
// #define exit(a, b) return cout << a, b;
 
// debugger
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
    os << "{ ";
    for(auto& y : x) os << y << ", ";
    return os << "}";
}
 
template <class X, class Y>
ostream & operator << (ostream & os, pair <X, Y> const& p) {
    return os << "[ " << p.first << ", " << p.second << " ]" ;
}

#define debug(stuff) cout << #stuff << ": " << stuff <<endl
#define debugc(stuff) cout << #stuff << ": "; for(auto x: stuff) cout << x << " "; cout << endl;
// 
 
#define loop(i,a,b) for(ll i=a;i<b;i++)
#define all(v) v.begin(), v.end() 
 
#define print(stuff) cout << stuff << endl
#define printc(stuff) for(auto x: stuff) cout << x << " "; cout << endl;
#define printPrec(stuff) cout << fixed << setprecision(15) << stuff << endl;
#define len length
#define ret0 return 0
#define ret return 
 
 
#define ll long long
#define ld long double
#define fi first
#define endl '\n'
#define se second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define fill(ar, x) memset(ar, x, sizeof ar)
#define sz(a) (ll)(a).size()
 
#define vl vector<ll> 
#define sl set<ll>
#define pll pair<ll, ll>
#define mll map<ll, ll> 
#define pq priority_queue<ll>
 
// typedef tree<ll,null_type,less<ll>,rb_tree_tag,
// tree_order_statistics_node_update> indexed_set;
 
#define inf (long long int) 1e18
#define eps 0.000001
#define mod 1000000007
#define mod1 998244353
#define MAXN (ll)1e6+5
#define N (1ll<<10)
#define pi 3.141592653589793238462643

ll h, w;
ll x1, yy1, x2, y2;
string s[1005];
vector<pll> adj[MAXN];
ll dis[MAXN];
bool processed[MAXN] = {false};
ll conv(ll x, ll y){
    return x * w + y;
}

bool in(ll x, ll y){
    if(x >= 0 && x < h && y >= 0 && y < w) return true;
    else return false;
}

void dij(ll x){
    for (ll i = 0; i < h * w; i++) dis[i] = inf;
    dis[x] = 0;
    priority_queue<pll> q;
    q.push({0,x});
    while (!q.empty()) {
        int a = q.top().second; q.pop();
        // trace(a);
        if (processed[a]) continue;
        processed[a] = true;
        for (auto u : adj[a]) {
            int b = u.second, w = u.first;
            if (dis[a] + w < dis[b]) {
                dis[b] = dis[a]+w;
                q.push({-dis[b],b});
            }
        }
    }
}

void solve(){
    cin >> h >> w;
    cin >> x1 >> yy1;
    cin >> x2 >> y2;
    x1--, yy1--, x2--, y2--;

    // string s[h];
    loop(i,0,h){
        cin >> s[i];
    }
    // ret;
    loop(i,0,h){
        loop(j,0,w){
            if(s[i][j] == '.'){
                ll a = conv(i, j);                       
                if(in(i + 1, j) && s[i + 1][j] == '.'){
                    adj[a].pb(mp(0ll, conv(i + 1, j)));
                }
                if(in(i - 1, j) && s[i - 1][j] == '.'){
                    adj[a].pb(mp(0ll, conv(i - 1, j)));
                }
                if(in(i, j + 1) && s[i][j + 1] == '.'){
                    adj[a].pb(mp(0ll, conv(i, j + 1)));
                }
                if(in(i, j - 1) && s[i][j - 1] == '.'){
                    adj[a].pb(mp(0ll, conv(i, j - 1)));
                }
                for(ll k = -1; k <= 1; k++){
                    if(in(i - 2, j + k) && s[i - 2][j + k] == '.') adj[a].pb(mp(1ll, conv(i - 2, j + k)));
                    if(in(i + k, j + 2) && s[i + k][j + 2] == '.') adj[a].pb(mp(1ll, conv(i + k, j + 2)));
                    if(in(i + 2, j + k) && s[i + 2][j + k] == '.') adj[a].pb(mp(1ll, conv(i + 2, j + k)));
                    if(in(i + k, j - 2) && s[i + k][j - 2] == '.') adj[a].pb(mp(1ll, conv(i + k, j - 2)));                    
                }

                if(in(i - 2, j - 2) && s[i - 2][j - 2] == '.') adj[a].pb(mp(1ll, conv(i - 2, j - 2)));
                if(in(i - 2, j + 2) && s[i - 2][j + 2] == '.') adj[a].pb(mp(1ll, conv(i - 2, j + 2)));
                if(in(i + 2, j + 2) && s[i + 2][j + 2] == '.') adj[a].pb(mp(1ll, conv(i + 2, j + 2)));
                if(in(i + 2, j - 2) && s[i + 2][j - 2] == '.') adj[a].pb(mp(1ll, conv(i + 2, j - 2)));

                if(in(i - 1, j - 1) && s[i - 1][j - 1] == '.') adj[a].pb(mp(1ll, conv(i - 1, j - 1)));
                if(in(i - 1, j + 1) && s[i - 1][j + 1] == '.') adj[a].pb(mp(1ll, conv(i - 1, j + 1)));
                if(in(i + 1, j + 1) && s[i + 1][j + 1] == '.') adj[a].pb(mp(1ll, conv(i + 1, j + 1)));
                if(in(i + 1, j - 1) && s[i + 1][j - 1] == '.') adj[a].pb(mp(1ll, conv(i + 1, j - 1)));
                   
            }
        }
    }
    // ret;
    ll firr = conv(x1, yy1);
    ll secc = conv(x2, y2);

    // loop(i,0,16){
    //     trace(i, adj[i]);
    // }

    dij(firr);
    if(dis[secc] == inf) print(-1);
    else print(dis[secc]);

}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #ifndef ONLINE_JUDGE
        start_routine();
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
 
    ll t = 1;
    // cin>>t;
    while(t--){
        solve();
    }
        
    #ifndef ONLINE_JUDGE
        end_routine();
    #endif
}


Measured memory_bytes: 168700