#include <bits/stdc++.h>
#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rrep(i, n) for (int i = 1; i <= (n); ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define rrng(a) a.rbegin(), a.rend()
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
#define limit(x, l, r) max(l, min(x, r))
#define lims(x, l, r) (x = max(l, min(x, r)))
#define isin(x, l, r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define uni(x) x.erase(unique(rng(x)), x.end())
#define show(x) cout << #x << " = " << x << endl;
#define print(x) cout << x << endl;
#define PQ(T) priority_queue<T, v(T), greater<T>>
#define bn(x) ((1 << x) - 1)
#define dup(x, y) (((x) + (y)-1) / (y))
#define newline puts("")
#define v(T) vector<T>
#define vv(T) v(v(T))
using namespace std;
typedef long long int ll;
typedef unsigned uint;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
typedef vector<T> vt;
const int MAX_V = 1000100;
int h, w;

const ll INF = 1000000007;
struct edge {
  int to;
  ll cost;
};
vector<edge> G[MAX_V];

vl dijkstra(int V, int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  vl d(V,INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.se;
    if (d[v] < p.first) continue;
    rep(i, sz(G[v])) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
  return d;
}

int main() {
  cin >> h >> w;
  int ch,cw;
  cin >> ch >> cw;
  int dh,dw;
  cin >> dh >> dw;
  vector<string> a(h);
  rep(i, h)cin >> a[i];
  const int dx[] = {-1, 1, 0, 0};
  const int dy[] = {0, 0, -1, 1};
  const int wx[] = {-2,-2,-2,-2,-2,-1,-1,-1,-1,0,0,1,1,1,1,2,2,2,2,2};
  const int wy[] = {-2,-1,0,1,2,-2,-1,1,2,-2,2,-2,-1,1,2,-2,-1,0,1,2};

  rep(i, h) {
    rep(j, w) {
      rep(k, 4) {
        int ny = i + dy[k];
        int nx = j + dx[k];
        if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
        int from = i * w + j;
        int to = ny * w + nx;
        edge e1, e2;
        e1.to = to;
        e2.to = from;
        if(a[i][j] == '#')continue;
        if(a[ny][nx] == '#')continue;
        e1.cost = 0;
        e2.cost = 0;
        G[from].push_back(e1);
        G[to].push_back(e2);
      }
      rep(k, 20) {
        int ny = i + wy[k];
        int nx = j + wx[k];
        if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
        if(a[i][j] == '#')continue;
        if(a[ny][nx] == '#')continue;
        int from = i * w + j;
        int to = ny * w + nx;
        edge e1, e2;
        e1.to = to;
        e2.to = from;
        e1.cost = 1;
        e2.cost = 1;
        G[from].push_back(e1);
        G[to].push_back(e2);
      }
    }
  }
  ll ans = 1LL << 60;
  ch--;dh--;
  auto dist = dijkstra(MAX_V,ch * w + cw-1);
  int k = dh*w + dw-1;
  mins(ans,dist[k]);
  if(ans == INF)ans = -1;
  cout << ans << endl;
  return 0;
}


Measured memory_bytes: 292276