#line 1 "cplib/template.cpp"
#include<bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i = 0;i < n;i++)
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()

template<class T> bool chmax(T& a,T b){ if(a > b){ a = b; return true; }else return false; }
template<class T> bool chmin(T& a,T b){ if(a < b){ a = b; return true; }else return false; }

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vl = vector<ll>;
using Pi = pair<int,int>;
using Pl = pair<ll,ll>;
using vpi = vector<Pi>;
using vpl = vector<Pl>;

#line 1 "cplib/debug.cpp"
#define debug(arr) cout << #arr << " = " << arr << '\n'
#define debug2(a,b) cout << "[" << #a << "," << #b << "] = " << "[" << a << "," << b << "]" << '\n'
template<class T> ostream &operator << (ostream& out, const vector<T>& arr) {
	cout << "{"; for (int i = 0; i < arr.size(); i++)cout << (!i ? "" : ", ") << arr[i]; cout << "}";
	return out;
}
template<class T> ostream &operator << (ostream& out, const vector<vector<T> >& arr) {
	cout << "{\n"; for (auto& vec : arr)cout << "  " << vec << ",\n"; cout << "}";
	return out;
}
template<class S,class T> ostream &operator << (ostream& out, const pair<S,T>& p){
  cout << "{" << p.first << "," << p.second << "}" << '\n';
  return out;
}
template<class T> istream &operator >> (istream& in, vector<T>& arr) {
	for (auto& i : arr)cin >> i; return in;
}
#line 1 "cplib/graph/template.cpp"
template<class T> struct Edge{
  int from,to; T cost;
  Edge(int from,int to,T cost):from(from),to(to),cost(cost){}
  Edge(){}
};
template<class T> struct Graph{
  int n;
  vector<vector<Edge<T>>> g;
  Graph(int n):n(n){
    g.resize(n);
  }
  void add_edge(int from,int to){
    g[from].emplace_back(from,to,1);
  }
  void add_edge(int from,int to,T cost){
    g[from].emplace_back(from,to,cost);
  }
  vector<Edge<T>>& operator[](int i){ return g[i]; }
};
#line 2 "cplib/graph/dijkstra.cpp"
template<class T> struct Dijkstra{
  #define INF (1LL << 55)
  using P = pair<T,int>;
  Graph<T> G;
  vector<T> d;
  vector<int> prev;
  Dijkstra(Graph<T>& G):G(G){}
  void solve(int s){
    d.assign(G.n,INF);
    prev.assign(G.n,-1);
    d[s] = 0;
    priority_queue<P,vector<P>,greater<P> > que;
    que.push(P(0,s));
    while(que.size()){
      P p = que.top();que.pop();
      int v = p.second;
      if(d[v] < p.first) continue;
      for(int i = 0;i < G[v].size();i++){
        Edge<T>& e = G[v][i];
        if(d[e.to] > d[v] + e.cost){
          d[e.to] = d[v] + e.cost;
          prev[e.to] = v;
          que.push(P(d[e.to] , e.to));
        }
      }
    }
  }
  bool reachable(int t){
    return d[t] != INF;
  }
  vector<int> get_path(int t){
    vector<int> path;
    for(;t != -1;t = prev[t]){ path.push_back(t); }
    reverse(path.begin(),path.end());
    return path;
  }
  T& operator[](int i){return d[i];}
};
#line 3 "main.cpp"

int h,w;
int sx,sy,gx,gy;
string g[1000];

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

int main(){

  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> h >> w;
  cin >> sx >> sy >> gx >> gy;
  sx--,sy--,gx--,gy--;
  REP(i,h)cin >> g[i];

  auto id = [=](int x,int y) -> int{
    return x * w + y;
  };
  auto inside = [=](int x,int y) -> bool{
    return x >= 0 && x < h && y >= 0 && y < w;
  };

  Graph<ll> G(h * w);
  REP(i,h)REP(j,w){
    if(g[i][j] == '#') continue;
    REP(d,4){
      int nx = i + dx[d];
      int ny = j + dy[d];
      if(inside(nx,ny) && g[nx][ny] == '.'){
        int from = id(i,j);
        int to = id(nx,ny);
        G.add_edge(from,to,0);
      }
    }
    for(int dx = -2;dx <= 2;dx++){
      for(int dy = -2;dy <= 2;dy++){
        if(abs(dx) + abs(dy) > 1){
          int nx = i + dx;
          int ny = j + dy;
          if(inside(nx,ny) && g[nx][ny] == '.'){
            int from = id(i,j);
            int to = id(nx,ny);
            G.add_edge(from,to,1);
          }
        }
      }
    }
  }
  
  Dijkstra<ll> D(G);
  D.solve(id(sx,sy));
  if(!D.reachable(id(gx,gy))){
    cout << -1 << '\n';
  }else{
    cout << D[id(gx,gy)] << '\n';
  }
  return 0;
}


Measured memory_bytes: 296136