#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;
#define PI 3.141592653589793

/* dijkstra.cpp
    ダイクストラ法で、ある頂点から各頂点への最短距離を求めるアルゴリズム
    負の辺が含まれる場合はうまく計算出来ないので、ベルマンフォード法を用いる
 
    verified: AOJ GRL_1_A
        http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A&lang=jp
*/
 
#include <bits/stdc++.h>
using namespace std;
 
struct Edge {
    long long to;
    double cost;
};
using Graph = vector<vector<Edge>>;
using P = pair<int, int>;
 
/* dijkstra(G,s,dis,prev)
    入力：グラフ G, 開始点 s, 距離を格納する dis, 最短経路の前の点を記録するprev
    計算量：O(|E|log|V|)
    副作用：dis, prevが書き換えられる
*/
void dijkstra(const Graph &G, int s, vector<int> &dis, vector<int> &prev) {
    int N = G.size();
    dis.resize(N, inf);
    prev.resize(N, -1);
    priority_queue<P, vector<P>, greater<P>> pq;  // the least element is top. first:cost, second: node
    dis[s] = 0;
    pq.emplace(dis[s], s);
    while (!pq.empty()) {
        P p = pq.top();  // the least element
        pq.pop();
        int v = p.second;
        if (dis[v] < p.first) {
            continue;
        }
        for (auto &e : G[v]) {
            if (dis[e.to] > dis[v] + e.cost) {
                dis[e.to] = dis[v] + e.cost;
                prev[e.to] = v;
                pq.emplace(dis[e.to], e.to);
            }
        }
    }
}
 
/* get_path(prev, t)
    入力：dijkstra で得た prev, ゴール t
    出力： t への最短路のパス
*/
vector<int> get_path(const vector<int> &prev, int t) {
    vector<int> path;
    for (int cur = t; cur != -1; cur = prev[cur]) {
        path.push_back(cur);
    }
    reverse(path.begin(), path.end());
    return path;
}

int main(){
  int h, w, ch, cw, dh, dw; cin >> h >> w >> ch >> cw >> dh >> dw;
  ch--; cw--; dh--; dw--;
  string s[h];
  rep(i, h){
    cin >> s[i];
  }
  Graph G(1010100);
  rep(i, h){
    rep(j, w){
      if(s[i][j]=='#') continue;
      if(i>0 && s[i-1][j]!='#'){
        G[i*w+j].push_back({(i-1)*w+j, 0}); G[(i-1)*w+j].push_back({i*w+j, 0});
      }
      if(i<h-1 && s[i+1][j]!='#' ){
        G[i*w+j].push_back({(i+1)*w+j, 0}); G[(i+1)*w+j].push_back({i*w+j, 0});
      }
      if(j>0 && s[i][j+1]!='#'){
        G[i*w+j].push_back({i*w+j-1, 0}); G[i*w+j-1].push_back({i*w+j, 0});
      }
      if(j<w-1 && s[i][j+1]!='#'){
        G[i*w+j].push_back({i*w+j+1, 0}); G[i*w+j+1].push_back({i*w+j, 0});
      }
      int ue = i-2; int hi = j-2;
      rep(ii, 5){
        rep(jj, 5){
          if(abs(i-ii)+abs(j-jj)<=1) continue;
          if(ue+ii>=0 && hi+jj>=0 && ue+ii<h && hi+jj<w && s[ue+ii][hi+jj]!='#'){
            G[(ue+ii)*w+hi+jj].push_back({i*w+j, 1});
            G[i*w+j].push_back({(ue+ii)*w+hi+jj, 1});
          }
        }
      }
    }
  }
  vector<int> dis;
  vector<int> prev;
  dijkstra(G, ch*w+cw, dis, prev);
  if(dis[dh*w+dw]>=inf){
    cout << -1 << endl; return 0;
  }
  cout << dis[dh*w+dw] << endl;
}

Measured memory_bytes: 378296