//********************************************************************//
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define RANGE(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define DFOR(i, a, b) for(int i = a; i > b; --i)
#define DEB(x) cout << #x << ": " << x << endl
#define ALL(v) v.begin(), v.end() 
#define SORT(v) sort(ALL(v))
#define DISPV(v) { for(auto x___: v) cout << x___ << " "; cout << endl; }
#define DISPM(m) { for(auto x____: m){ cout << x____.first << ": " << x____.second << endl; } };
#define DISPMV(m) { for(auto x_____: m){ cout << x_____.first << ": " ;DISPV(x_____.second);} };
using LL = long long;
using VI = vector <int>;
using VL = vector <long long>;
using VVI = vector<VI>;
using VVL = vector <VL>;
using MII = map<int, int>;
using MIVI = map<int, VI>;
using MLL = map<LL, LL>;
int READ_INT(){int temp;cin>>temp;return temp;}      // read an int
LL READ_LONG(){LL temp;cin>>temp;return temp;}      // read a long long

const int MOD = int(1e9) + 7;
const int INF = 1e9 + 5;
const double PI = acos(-1.0); //M_PI;
const double EPS = 1e-9;
//********************************************************************//

int rows, cols;    // rows, cols
char grid[1005][1005];
int dist[1005][1005], visited[1005][1005];

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

bool ok(int x, int y){
    return x >= 1 && x <= rows && y >= 1 && y <= cols && !visited[x][y];
}

void bfs(int x, int y){
    dist[x][y] = 0;
    visited[x][y] = 1;
    queue<pair<int, int>>q, cur;
    q.push({x, y});
    while(!q.empty()){
        int x1 = q.front().first, y1 = q.front().second;
        // cout << x1 << ", " << y1 << endl;
        // READ_INT();
        cur.push(q.front());
        q.pop();
        RANGE(k, 4){
            int x2 = x1 + dx[k], y2 = y1 + dy[k];
            if(ok(x2, y2) && grid[x2][y2] == '.'){
                dist[x2][y2] = dist[x1][y1];
                visited[x2][y2] = 1;
                q.push({x2, y2});
            }
        }
        if(q.empty()){
            // cout << "here\n";
            while(!cur.empty()){
                int x1 = cur.front().first, y1 = cur.front().second;
                cur.pop();

                // cout << x1 << ", " << y1 << endl;
                // READ_INT();
                
                for(int x2 = x1-2; x2 <= x1+2; ++x2){
                    for(int y2 = y1-2; y2 <= y1+2; ++y2){
                        if(ok(x2, y2) && grid[x2][y2] == '.'){
                            dist[x2][y2] = dist[x1][y1] + 1;
                            visited[x2][y2] = 1;
                            q.push({x2, y2});
                        }
                    }
                }
            }
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int x1, y1, x2, y2;
    cin >> rows >> cols;
    cin >> x1 >> y1 >> x2 >> y2;
    RANGE(i,rows){
        RANGE(j,cols){
            cin >> grid[i+1][j+1];
        }
    }
    memset(visited, 0, sizeof(visited));
    RANGE(i,1005){
        RANGE(j,1005)
            dist[i][j] = INF;
    }
    bfs(x1, y1);
    if(dist[x2][y2] >= INF)
        cout << -1 << endl;
    else
        cout << dist[x2][y2] << endl;
    return 0;
}



/* complie flags
-Wall -Wextra -pedantic -std=c++11 -O2 -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector
*/

Measured memory_bytes: 12512