#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
#include <numeric>
#include <set>
#include <unordered_set>
#include <queue>
#include <cmath>
#include <bitset>

using namespace std;
#define ll long long
#define rep(i, n) for(int i = 0;i < n;i++)
#define FOR(i, n, m) for(int i=n; i<m; ++i)

using Graph = vector<vector<int>>;

// 深さ優先探索
vector<bool> seen;
void dfs(const Graph &G, int v) {
    seen[v] = true; // v を訪問済にする

    // v から行ける各頂点 next_v について
    for (auto next_v : G[v]) { 
        if (seen[next_v]) continue; // next_v が探索済だったらスルー
        dfs(G, next_v); // 再帰的に探索
    }
}

bool IsPrime(int num)
{
    if (num < 2) return false;
    else if (num == 2) return true;
    else if (num % 2 == 0) return false; // 偶数はあらかじめ除く

    double sqrtNum = sqrt(num);
    for (int i = 3; i <= sqrtNum; i += 2)
    {
        if (num % i == 0)
        {
            // 素数ではない
            return false;
        }
    }

    // 素数である
    return true;
}

int main() {
  ll H, W, C1, C2, D1, D2;
  char m[1010][1010];
  ll f[1010][1010];
  vector<pair<ll,ll>> p;
  
  cin >> H >> W >> C1 >> C2 >> D1 >> D2;
  
  rep(i,H){
    rep(j,W){
      cin >> m[i][j];
      f[i][j] = -1;
      if(m[i][j] == '.'){
        p.push_back(pair(i,j));
      }
    }
  }
  
  queue<pair<ll,ll>> q;
  q.push(pair(C1-1, C2-1));
  f[C1-1][C2-1] = 0;
  queue<pair<ll,ll>> tm;
  tm.push(pair(C1-1, C2-1));
  
  while(!q.empty()){
    ll x = q.front().first;
    ll y = q.front().second;
    
    q.pop();
    
    if(x>0 && m[x-1][y]=='.' && f[x-1][y]==-1){
      f[x-1][y] = 0;
      q.push(pair(x-1, y));
      tm.push(pair(x-1, y));
    }
    if(x<H-1 && m[x+1][y]=='.' && f[x+1][y]==-1){
      f[x+1][y] = 0;
      q.push(pair(x+1, y));
      tm.push(pair(x+1, y));
    }
    if(y>0 && m[x][y-1]=='.' && f[x][y-1]==-1){
      f[x][y-1] = 0;
      q.push(pair(x, y-1));
      tm.push(pair(x, y-1));
    }
    if(y<W+1 && m[x][y+1]=='.' && f[x][y+1]==-1){
      f[x][y+1] = 0;
      q.push(pair(x, y+1));
      tm.push(pair(x, y+1));
    }
    
  }
  
  ll count = 0;

  while(1){
    queue<pair<ll,ll>> w;
    //queue<pair<ll,ll>> tm;
    while(!tm.empty()){
      ll i = tm.front().first;
      ll j = tm.front().second;
      tm.pop();
      rep(k,5){
        rep(l,5){
          if((i-2+k >= 0) && (i-2+k < H) && (j-2+l >= 0) && (j-2+l < W) && m[i-2+k][j-2+l]=='.' && f[i-2+k][j-2+l]==-1){
            f[i-2+k][j-2+l] = count+1;
            w.push(pair(i-2+k, j-2+l));
          }
        }
      }
    }
    count++;

    /*while(!tm.empty()){
      ll x = tm.front().first;
      ll y = tm.front().second;
      tm.pop();
      
      rep(k,5){
        rep(l,5){
          if((x-2+k >= 0) && (x-2+k < H) && (y-2+l >= 0) && (y-2+l < W) && m[x-2+k][y-2+l]=='.' && f[x-2+k][y-2+l]==-1){
            f[x-2+k][y-2+l] = count;
            w.push(pair(x-2+k, y-2+l));
          }
        }
      }
    }*/
    
    if(w.empty()){
      /*rep(i,H){
        rep(j,W){
          cout << f[i][j];
        }
        cout << endl;
      }*/
      cout << f[D1-1][D2-1] << endl;
      return 0;
    }
    
    while(!w.empty()){
      ll x = w.front().first;
      ll y = w.front().second;
      w.pop();
      tm.push(pair(x, y));
      
      if(x>0 && m[x-1][y]=='.' && f[x-1][y]==-1){
        f[x-1][y] = count;
        w.push(pair(x-1, y));
        tm.push(pair(x-1, y));
      }
      if(x<H-1 && m[x+1][y]=='.' && f[x+1][y]==-1){
        f[x+1][y] = count;
        w.push(pair(x+1, y));
        tm.push(pair(x+1, y));
      }
      if(y>0 && m[x][y-1]=='.' && f[x][y-1]==-1){
        f[x][y-1] = count;
        w.push(pair(x, y-1));
        tm.push(pair(x, y-1));
      }
      if(y<W+1 && m[x][y+1]=='.' && f[x][y+1]==-1){
        f[x][y+1] = count;
        w.push(pair(x, y+1));
        tm.push(pair(x, y+1));
      }  
    }
    
  }
  
  
  /*for(auto x: p){
    cout << x.first << " " << x.second << endl;
  }
  rep(i,H){
    rep(j,W){
      cout << f[i][j];
    }
    cout << endl;
  }*/
  
}

Measured memory_bytes: 19952