#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
#include<queue>
#include<tuple>
#include<utility>
#include<map>
#include<math.h>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define range(a) a.begin(), a.end()
#define endl "\n"
#define Yes() cout << "Yes" << endl
#define No() cout << "No" << endl
using Graph = vector<vector<ll>>;
const unsigned long long mod = 1e9 + 7;
const long long INF = 1LL<<60;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
void chmin(long long &a, long long b) { if (a > b) a = b; }
void chmax(long long &a, long long b) { if (a < b) a = b; }

int H, W, sh, sw, gh, gw, cost=0;
vector<vector<int>> dist; // 全頂点を「未訪問」に初期化
vector<string> maze;
vector<pair<int, int>> route, start;

void check(int sh, int sw){
    queue<pair<int, int>> que;
    // 初期条件 (頂点 0 を初期ノードとする)
    dist.at(sh).at(sw) = cost;
    que.push(make_pair(sh, sw)); // 0 を橙色頂点にする
    route.push_back(make_pair(sh, sw));
    pair<int,int> v;
    
    // BFS 開始 (キューが空になるまで探索を行う)
    while (!que.empty()) {
        v = que.front(); // キューから先頭頂点を取り出す
        que.pop();

        // 四方向を探索
        for (int dir = 0; dir < 4; ++dir) {
        int nh = v.first + dx[dir];
        int nw = v.second + dy[dir];

        // 場外アウトしたり、移動先が壁の場合はスルー
        if (nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
        if (maze[nh][nw] == '#') continue;

        // 移動先が探索済みの場合
        if (dist.at(nh).at(nw)!=-1) continue;
        
        dist.at(nh).at(nw) = cost;
        route.push_back(make_pair(nh, nw));
        que.push(make_pair(nh,nw));
        
        }
    }
}


int main() {
    cin>>H>>W;
    //スタートの座標を(sh,sw)、ゴールの座標を(gh,gw)
    cin>>sh>>sw>>gh>>gw;
    sh--;
    sw--;
    gh--;
    gw--;
    maze.resize(H);
    dist.resize(H);
    FOR(i, 0, H)
    dist.at(i).resize(W, -1);

    // BFS のためのデータ構造
    FOR(i,0,H){
            cin>>maze.at(i);
    }

    check(sh, sw);
    
    cost++;
 
    if (dist.at(gh).at(gw) != -1)
    {
        cout << dist.at(gh).at(gw) << endl;
        return 0;
    }
    
    while (1)
    {
        // 四方向を探索
        FOR(i, 0, route.size())
        {
            FOR(dir1, -2, 3)
            {
                FOR(dir2, -2, 3)
                {
                    int nh = route.at(i).first + dir1;
                    int nw = route.at(i).second + dir2;

                    // 場外アウトしたり、移動先が壁の場合はスルー
                    if (nh < 0 || nh >= H || nw < 0 || nw >= W)
                        continue;
                    if (maze[nh][nw] == '#')
                        continue;
                    
                    // 移動先が探索済みの場合
                    if (dist.at(nh).at(nw) != -1)
                        continue;

                    dist.at(nh).at(nw) = cost;
                    start.push_back(make_pair(nh, nw));
                }
            }
        }

        route.clear();
        if (dist.at(gh).at(gw) != -1)
        {
            cout << dist.at(gh).at(gw) << endl;
            return 0;
        }
        if(start.size()==0){
            cout << -1 << endl;
            return 0;
        }

        FOR(i, 0, start.size())
        {
            /*
            // 移動先が探索済みの場合
            if (dist.at(start.at(i).first).at(start.at(i).second) != -1)
                continue;
                */
            check(start.at(i).first, start.at(i).second);
        }

        if (dist.at(gh).at(gw) != -1)
        {
            cout << dist.at(gh).at(gw) << endl;
            return 0;
        }

        start.clear();
        cost++;
    }

    return 0;
}









Measured memory_bytes: 9472