#ifndef CLion
#pragma GCC optimize ("O3")
#endif

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/numeric>

#define F first
#define S second
#define pb push_back
#define ll long long
#define all(x) x.begin() , x.end()
#define rep(i,s,e) for (int i = s; i < e; ++i)
#define rev(i,s,e) for (int i = s; i > e; --i)
#define mem(a,v) memset(a , v , sizeof a)
//#define mod(x,m) ((x%m + m)%m)
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
        tree_order_statistics_node_update>;

const int N = 1e3 + 9 , M = 1e6 + 99;
int n , m , a ,b , x , y , cid = 1;
int comp[N][N];
bool inq[N][N];
char g[N][N];

int dx[] = {-1,1,0,0,-1,-1,1,1};
int dy[] = {0,0,-1,1,-1,1,1,-1};

bool ok( int i , int j ){
    return i >= 0 && j >= 0 && i < n && j < m && g[i][j] == '.';
}

void bfs( int u , int v ){
    queue<pair<int,int>> q;
    q.push({u , v});

    while ( q.size() ){
        auto cur = q.front(); q.pop();
        comp[cur.F][cur.S] = cid;
        inq[cur.F][cur.S] = false;
        rep(k,0,4){
            int xx = cur.F + dx[k];
            int yy = cur.S + dy[k];
            if ( ok(xx , yy) && !inq[xx][yy] && comp[xx][yy] == 0 ){
                inq[xx][yy] = true;
                q.push({xx , yy});
            }
        }
    }
}

int cost[M];
bool vis[M];
int ans = 1e9;
set<int> adj[M];
void dij( int u , int d){
    mem(cost, 0x3f);
    priority_queue<pair<int,int>> pq;
    pq.push({0 , u});
    cost[u] = 0;

    while ( pq.size() ){
        auto cur = pq.top(); pq.pop();
        cur.F *= -1;
        for ( int v : adj[cur.S] ){
            if ( cost[v] > cur.F + 1 ){
                cost[v] = cur.F + 1;
                pq.push({-cost[v] , v});
            }
        }
    }
    ans = min(ans , cost[d]);
}

void Main(int cse , bool last){
    cin >> n >> m;
    cin >> a >> b; a--; b--;
    cin >> x >> y; x--; y--;
    rep(i,0,n) rep(j,0,m) cin >> g[i][j];
    rep(i,0,n) rep(j,0,m) {
            if (g[i][j] == '.' && comp[i][j] == 0 ) bfs(i , j) , cid++;
    }

    rep(i,0,n) {
        rep(j,0,m) {
            rep(h,1,3){
                rep(v,1,3){
                    rep(k,0,8){
                        int xx = i + h * dx[k];
                        int yy = j + v * dy[k];
                        if ( ok(xx,yy) && comp[i][j] != 0 && comp[xx][yy] != 0 ){
                            adj[comp[i][j]].insert(comp[xx][yy]);
                            adj[comp[xx][yy]].insert(comp[i][j]);
                        }
                    }
                }
            }
        }
    }

    ans = 1e9;
    dij(comp[a][b] , comp[x][y]);
    cout << (ans == 1e9 ? -1 : ans);
}

int main(){
#ifndef CLion
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#endif
#ifdef CLion
    freopen( "in.txt" , "r" , stdin  );
//    freopen( "out.txt", "w" , stdout );
    clock_t st = clock();
#endif

    int t = 1;
//    cin >> t;
    for ( int cse = 1; cse <= t; ++cse ) Main(cse, cse == t);

#ifdef CLion
    clock_t en = clock();
    cout << "\n\nTime: " << fixed << (en - st - 0.0) / CLOCKS_PER_SEC;
#endif
    return 0;
}


Measured memory_bytes: 80716