#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define REPR(i,n) for(int i=n; i>-1; --i)
#define ALL(a) (a).begin(),(a).end()
#define FILL(a,n,x); REP(i,(n)){ (a)[i]=(x); }
#define CINA(a,n); REP(i,(n)){ cin >> (a)[i]; }
#define FILL2(a,n,m,x); REP(i,(n)){ REP(j,(m)){(a)[i][j]=(x);} }
#define CINA2(a,n,m); REP(i,(n)){ REP(j,(m)){cin >> (a)[i][j];} }
#define Liny "Yes\n"
#define Linn "No\n"
#define LINY "YES\n"
#define LINN "NO\n"

//cout << setfill('0') << right << setw(4) << 12; // "0012"
int keta(ll x){ if(x<10){return 1;} else{return keta(x/10) + 1;}}
int keta_wa(ll x){ if(x<10){return x;} else{return keta_wa(x/10) + x%10;} }
int ctoi(char c){ return ( (c>='0' && c<='9')? c - '0': 0 );}
int __stoi(string s){ return atoi(s.c_str()); }
ll sum(ll a[],ll N){ return accumulate(a,a+N,0LL);}
ll gcd(ll a,ll b){if(a<b)swap(a,b); return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){if(a<b){swap(a,b);} return a/gcd(a,b)*b;}
template<class T> void chmax(T& a, T b){ if(a<b){a=b;} }
template<class T> void chmin(T& a, T b){ if(a>b){a=b;} }
template<class T> bool isIn(T a,vector<T> v){ for(T x:v){ if(a==x){return true;}} return false;}
string strReplace(string s,string target, string replacement){
    if (!target.empty()) {
      std::string::size_type pos = 0;
      while ((pos = s.find(target, pos)) != std::string::npos) {
        s.replace(pos, target.length(), replacement);
        pos += replacement.length();
      }
    }
    return s;
}
const ll MOD = 1e9+7;
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MP make_pair

bool DEBUG = 0;
template<class T> void dprint(T s){
  if(DEBUG){ cout << s << "\n"; }
}

string board[1005];
ll dp[1005][1005];

const ll MAX = MOD;

struct four{
  int h,w,h_next,w_next;
};

void solve(){
  int H,W; cin>>H>>W;
  int CH,CW,DH,DW; cin>>CH>>CW>>DH>>DW;
  --CH;
  --CW;
  --DH;
  --DW;
  CINA(board,H);
  FILL2(dp,H,W,MAX);
  dp[CH][CW] = 0LL;
  queue<pii> q;
  queue<four> r;
  q.push(MP(CH,CW));
  while(!q.empty() || !r.empty()){
    while(!q.empty()){
      int h = q.front().first;
      int w = q.front().second;
      q.pop();
      bool flag = false;
      for(int i=-1;i<=1;++i){
        int h_next = h+i;
        if(h_next<0 || h_next>=H){continue;}
        for(int j=-1;j<=1;++j){
          if(abs(i)+abs(j)>1){continue;}
          int w_next = w+j;
          if(w_next<0 || w_next>=W){continue;}
          if(board[h_next][w_next]=='#'){ flag = true;continue;}
          if(dp[h_next][w_next]>dp[h][w]){
            dp[h_next][w_next] = dp[h][w];
            q.push(MP(h_next,w_next));
          }
          
        }
      }
      if(!flag){continue;}
      for(int i=-2;i<=2;++i){
        int h_next = h+i;
        if(h_next<0 || h_next>=H){continue;}
        for(int j=-2;j<=2;++j){
          int w_next = w+j;
          if(w_next<0 || w_next>=W){continue;}
          if(board[h_next][w_next]=='#'){continue;}
          if(dp[h_next][w_next]>dp[h][w]+1){
            r.push({h,w,h_next,w_next});
          }
        }
      }
    }
    while(!r.empty()){
      int h = r.front().h;
      int w = r.front().w;
      int h_next = r.front().h_next;
      int w_next = r.front().w_next;
      r.pop();
      if(dp[h_next][w_next]>dp[h][w]+1){
        dp[h_next][w_next] = dp[h][w] + 1;
        q.push(MP(h_next,w_next));
      }
    }
  }
  if(dp[DH][DW]==MAX){dp[DH][DW] = -1;}
  if(DEBUG){
    REP(i,H){
      REP(j,W){
        cout << dp[i][j] << " ";
      }
      cout << "\n";
    }
  }
  cout << dp[DH][DW] << "\n";
  return;
}

int main(int argc, char *argv[]){
  if(argc>1 && argv[1][0]=='D'){ DEBUG = 1;}
  solve();
  return 0;
}


Measured memory_bytes: 13508