#include <iostream>
#include <algorithm>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <stack>
#include <cstring>
#include <fstream>
#include <sstream>
#include <numeric>
#include <functional>
#include <queue>
#include <iomanip>
 

using namespace std;



// Debugging Template
/*  ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^  */

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

/*  ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^    ^^  */
void file_io()
{
    freopen("ariprog.in", "r", stdin);
    freopen("ariprog.out", "w", stdout);
}

typedef pair<int,int> pii;
typedef long long ll;

const int V = int(2e5);
const int INF = int(2e9);

char mat[1000][1000];
int mark[1000][1000];
int mark2[1000][1000];
int marks[1000*1000];
int h, w, c1, c2, t1, t2;
int group_num = 0;


void solve(int r, int c) 
{
    if (r < 0 || r >= h || c < 0 || c >= w) 
        return;

    if (mark[r][c] != 0) 
        return;
    
    if (mat[r][c] == '#') 
        return;

    mark[r][c] = group_num;

    solve(r+1, c);
    solve(r-1, c);
    solve(r, c+1);
    solve(r, c-1);
}

int main() 
{
    
    // input
    cin >> h >> w >> c1 >> c2 >> t1 >> t2;
    c1--;
    c2--;
    t1--;
    t2--;

    for (int i=0; i<h; ++i) 
        for (int j=0; j<w; ++j)
            cin >> mat[i][j];
    

    // stage 1
    for (int i=0; i<h; ++i)
    {
        for (int j=0; j<w; ++j) 
        {
            if (mark[i][j] == 0 && mat[i][j] == '.') 
            {
                group_num++;
                solve(i, j);
            }
        }
    }



    if (mark[c1][c2] == mark[t1][t2])
    {
        cout << 0 << endl;
        return 0;
    }



    
    // stage 2
    vector<vector<int>> ls(group_num + 10000);
    set<pair<int, int>> remset;
    for (int i=0; i<h; ++i) 
    {
        for (int j=0; j<w; ++j)
        {
            if (mat[i][j] == '#') continue;
            for (int k=i-2; k<=i+2; ++k) 
            {
                for (int l=j-2; l<=j+2; ++l)
                {
                    if (k<0 || k>=h || l<0 || l>=w) continue;
                    if (mat[k][l] == '#') continue;
                    if (mark[i][j] == mark[k][l]) continue;
                    int g1= mark[i][j], g2 = mark[k][l];
                    if (g1 > g2) swap(g1, g2);
                    
                    if (remset.count({g1, g2}) != 0) continue;
                    
                    remset.insert({g1, g2});
                    ls[g1].push_back(g2);
                    ls[g2].push_back(g1);

                }
            }
        }
    }
    //debug(remset);
  
    queue<int> Q;
    Q.push(mark[c1][c2]);
    marks[mark[c1][c2]] = 1;
    vector<int> level(group_num+1);
    level[mark[c1][c2]]=0;
    while (!Q.empty()) 
    {
        int v = Q.front();
        Q.pop();
        
        
        if (v == mark[t1][t2]) 
        {
            //debug(level);
            cout << level[v] << endl;
            return 0;
        }
        for (auto child : ls[v]) 
        {
            
            if (marks[child]) continue;
            level[child] = level[v] + 1;
            Q.push(child);
            marks[child] = 1;
            
            

        }
    }

    cout << -1 << endl;

    return 0;
}

/*
10 10
1 1
10 10  
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
*/

Measured memory_bytes: 25984