#include<iostream>
#include<unordered_map>
#include<bitset>
#include<math.h>
#include<vector>
#include<set>
#include<algorithm>
#include<ctype.h>
#include<unordered_set>
#include<string>
#include<iomanip>
#include<queue>
#include<limits>
#include<map>
#include<stack>
#include<iterator>
#include<cstring>
 
#include<deque>
#define pi 3.141592653589793238
#include<chrono>
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#define MOD 1000000007
#define INF 999999999999999999 
#define pb push_back
#define ff first
#define ss second
 
#define mt make_tuple
#define ll long long
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;
 
 
typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const int N = 1e3 + 1;
ll h, w;
ll xa, ya,xb,yb;
string s[N];
ll dp[N][N];
bool visited[N][N]; 
bool valid(ll x, ll y){
    if(x <= 0 || x > h || y <= 0 || y > w){
        return false;
    }
    if(s[x - 1][y - 1] == '#'){
        return false;
    }
    return true;
}
void bfs(){
    priority_queue<tuple<ll,ll,ll>> q;
    q.push({0, xa, ya});
    //cout << xa << " "  << ya << "$$$"<<endl;
    dp[xa][ya] = 0;
    while(!q.empty()){
        tuple<ll,ll,ll> p = q.top();
        q.pop();
        ll x, y, z;
        tie(z, x, y) = p;
        //cout << x<< " " << y << endl;
        if(visited[x][y]){
            continue;
        }
        visited[x][y] = true;
        for(int i = x - 2; i <= x + 2; i++){
            for(int j = y - 2; j <= y + 2; j++){
                if(!valid(i, j)){
                    continue;
                }
                if(abs(x - i) + abs(y - j) == 0){
                    continue;
                }
                if(abs(x - i) + abs(y - j) == 1){
                    if(dp[i][j] > dp[x][y]){
                        dp[i][j] = dp[x][y];
                        q.push({-dp[i][j], i, j});
                    }
                    continue;
                }
                if(dp[i][j] > dp[x][y] + 1){
                    dp[i][j] = dp[x][y] + 1;
                    q.push({-dp[i][j], i, j});
                }
            }
        }
    }
}
int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    fast;
    ll T = 1, i, j;
    
    //cin >> T;
    while (T--) {
        cin >> h >> w;
        cin >> xa >> ya;
        cin >> xb >> yb;
        for(i = 0; i < h; i++){
            cin >> s[i];
        }
        for(i = 0; i <= h; i++){
            for(j = 0; j <= w; j++){
                dp[i][j] = INF;
            }
        }
        
        dp[xa][ya] = 0;
        bfs();
        for(i = 0; i <= h; i++){
            for(j = 0; j <= w; j++){
                //cout << dp[i][j] << " ";
            }
            //cout << endl;
        }
        if(dp[xb][yb] == INF){
            cout << -1;
        }
        else{
            cout << dp[xb][yb];
        }
    }
    return 0;
}

Measured memory_bytes: 13564