#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()

int main() {
  int h,w,sx,sy,gx,gy;
  cin >> h >> w;
  cin >> sx >> sy;
  cin >> gx >> gy;
  sx--;
  sy--;
  gx--;
  gy--;
  vector<string> S(h);
  for (int i = 0; i < h; i++)
  {
    cin >> S[i];
  }
  

  vector<vector<int>> A = {{-1,0},{1,0},{0,-1},{0,1}};
  vector<vector<int>> B;
  for (int i = -2; i < 3; i++)
  {
    for (int j = -2; j < 3; j++)
    {
      if (i!=0 && j!=0)
      {
        B.push_back({i,j});
      }
    }
    
  }
  int n = h*w;
  vector<vector<vector<int>>> M(n);
  for (int i = 0; i < h; i++)
  {
    for (int j = 0; j < w; j++)
    {
      if (S[i][j] == '.')
      {
        for (int k = 0; k < A.size(); k++)
        {
          int ai = i + A[k][0];
          int aj = j + A[k][1];
          if (0 <= ai && (ai < h && (0 <= aj && (aj < w && S[ai][aj] == '.'))))
          {
            M[i*w+j].push_back({ai*w+aj, 0});
          }
        }
        for (int k = 0; k < B.size(); k++)
        {
          int ai = i + B[k][0];
          int aj = j + B[k][1];
          if (0 <= ai && (ai < h && (0 <= aj && (aj < w && S[ai][aj] == '.'))))
          {
            M[i*w+j].push_back({ai*w+aj, 1});
          }
        }
        
      }
    }
  }

  vector<int>  D(n, pow(10,9));
  D[sx*w+sy] = 0;
  vector<int>  V(n, 0);
  priority_queue<vector<int>> Q;
  for (int i = 0; i < n; i++)
  {
    Q.push({-D[i], i});
  }

  int le,u,du,luv,alt,v;
  vector<int> q;
  le = Q.size();
  while (le > 0)
  {
    q = Q.top();
    Q.pop();
    u = q[1];
    du = -q[0];
    if (V[u] == 0)
    {
      V[u] = 1;
      le -= 1;
      for (int i = 0; i < M[u].size(); i++)
      {
        v = M[u][i][0];
        luv = M[u][i][1];
        if (V[v] == 0)
        {
          alt = du + luv;
          if (D[v] > alt)
          {
            D[v] = alt;
            Q.push({-alt, v});
          }
        }
      }
      
    }
  }




  int ans = D[gx*w+gy];
  if (ans > pow(10, 6) + 5)
  {
    ans = -1;
  }
  // for (int i = 0; i < n; i++)
  // {
  //   cout << i/w << " " << i%w << " " << D[i] << endl;
  // }
  


  cout << ans << endl;
}



### FIXED CODE ###

h, w = map(int,input().split())
sx, sy = map(int,input().split())
gx, gy = map(int,input().split())
S = [input() for i in range(h)]

sx-=1
sy-=1
gx-=1
gy-=1

A = [(-1,0),(1,0),(0,-1),(0,1)]
B = []
for i in range(-2,3):
    for j in range(-2,3):
        if i!= 0 or j!=0:
            B.append((i,j))
# print(B)

# O((V + E)log(V))
# Cは [[スタート頂点, ゴール頂点, 重み], ...] のリスト

M = [[] for i in range(h*w)]

for i in range(h):
    for j in range(w):
        if S[i][j] == ".":
            for a in A:
                ai = i+a[0]
                aj = j+a[1]
                if 0 <= ai < h and 0 <= aj < w and S[ai][aj] == ".":
                    M[i*w+j].append((ai*w+aj, 0))
            for b in B:
                bi = i+b[0]
                bj = j+b[1]
                if 0 <= bi < h and 0 <= bj < w and S[bi][bj] == ".":
                    M[i*w+j].append((bi*w+bj,1))


# for i in range(len(C)):

#     M[C[i][0]].append([C[i][1], C[i][2]])  # 無向グラフなら両方追加
#     M[C[i][1]].append([C[i][0], C[i][2]])  # 無向グラフなら両方追加

n = h*w

import heapq

big = 10**9
D = [big] * n  # 頂点0からの距離
P = [-1] * n  # 頂点0からの最短距離において、そこの直前の頂点(経路復元に利用)
D[sx*w+sy] = 0
V = [0] * n  # その頂点のD[i]が最短距離と確定したら1
Q = []  # 優先度付きキュー
# for v in range(n):
#     heapq.heappush(Q, (D[v], v))
heapq.heappush(Q, (0, sx*w+sy))

# le = n
while len(Q) > 0:
    # print(Q,le)
    q = heapq.heappop(Q)
    u = q[1]
    du = q[0]
    if V[u] == 0:
        V[u] = 1
        # le -= 1
        for i in range(len(M[u])):
            v = M[u][i][0]
            luv = M[u][i][1]
            # print(v)
            if V[v] == 0:
                alt = du + luv
                if D[v] > alt:
                    D[v] = alt
                    P[v] = u
                    heapq.heappush(Q, (alt, v))
                    # le += 1
                    # print(Q)
# print(D)
ans = D[gx*w+gy]
if ans > 10**7:
    ans = -1
print(ans)