// テンプレ
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define int long long
using P = pair<int, int>;

#define LOG(variable) cerr << #variable":\t" << (variable) << endl
#define LOGCON(i, container) for(int (i) = 0; (i) < (container).size(); ++(i)) cerr << (i) << ":\t" << (container)[(i)] << endl
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPS(i, r, n) for (int i = (r); i < (n); ++i)
#define REPR(i, n) for(int i = (n); i >= 0; --i) // from n to 0
#define REPRS(i, n, r) for(int i = (n); i >= (r); --i) // from n to r
#define REPOBJ(itr, obj) for(auto itr = (obj).begin(); itr != (obj).end() ; ++itr)
#define REPROBJ(itr, obj) for(auto itr = (obj).rbegin(), e = (obj).rend(); itr != e; ++itr)
#define COUTB(x) cout << (x) << "\n"
#define COUTS(x) cout << (x) << " "
#define PB push_back
#define SORT(obj) sort((obj).begin(), (obj).end())
#define SORTR(obj) sort((obj).begin(), (obj).end(), greater<>())
#define ALL(obj) (obj).begin(), (obj).end()
#define MOD 1000000007
#define PI (acos(-1))
template<typename T = int>
T in() {T a; cin >> a; return a;}

const int MAX = 1000;
const int dy[4]={0,1,0,-1}, dx[4]={1,0,-1,0}; // 4近傍の移動
int H,W;
int goal_y, goal_x;
int c_y, c_x;
bool g[MAX][MAX]; // 通れるマスならtrue
bool visited[MAX][MAX];
bool searched[MAX][MAX];

int bfs(int current, vector<P> search = {}) {
  vector<P> starts;
  if(current) {
    bool found_any = false;
    for(auto& search_p : search) {
      searched[search_p.first][search_p.second] = true;
      for(int i = -2; i < 3; ++i) {
        for(int j = -2; j < 3; ++j) {
          if(i == 0 && j == 0) continue;
          if(search_p.first+i < 0 || search_p.first+i >= H) continue;
          if(search_p.second+j < 0 || search_p.second+j >= W) continue;
          if(visited[search_p.first+i][search_p.second+j]) continue;
          if(!g[search_p.first+i][search_p.second+j]) continue;
          if(search_p.first+i == goal_y && search_p.second+j == goal_x) return current;
          // visited[h+i][search_p.second+j] = true;
          starts.push_back(P(search_p.first+i, search_p.second+j));
          found_any = true;
        }
      }
    }
    // REP(h, H) {
    //   REP(w, W) {
    //     if(visited[h][w] && !searched[h][w]) {
    //       searched[h][w] = true;
    //       for(int i = -2; i < 3; ++i) {
    //         for(int j = -2; j < 3; ++j) {
    //           if(i == 0 && j == 0) continue;
    //           if(h+i < 0 || h+i >= H) continue;
    //           if(w+j < 0 || w+j >= W) continue;
    //           if(visited[h+i][w+j]) continue;
    //           if(!g[h+i][w+j]) continue;
    //           if(h+i == goal_y && w+j == goal_x) return current;
    //           // visited[h+i][w+j] = true;
    //           starts.push_back(P(h+i, w+j));
    //           found_any = true;
    //         }
    //       }
    //     }
    //   }
    // }
    if(!found_any) return -1;
  } else {
    // 最初
    starts.push_back(P(c_y, c_x));
  }
  vector<P> search_next;
  for(auto& start_pair : starts) {
    queue<P> que;
    P current_p = start_pair;
    visited[current_p.first][current_p.second] = true;
    search_next.push_back(P(current_p.first, current_p.second));
    que.push(current_p);
    while(!que.empty()) {
      current_p = que.front();
      que.pop();
      for(int i = 0; i < 4; ++i) {
        int next_y = current_p.first + dy[i];
        int next_x = current_p.second + dx[i];
        // 範囲外
        if(next_y < 0 || next_y >= H) continue;
        if(next_x < 0 || next_x >= W) continue;

        if(next_y == goal_y && next_x == goal_x) return current; // 目的のマスについた

        // 通れないまたはすでに到達済み
        if(!g[next_y][next_x]) continue;
        if(visited[next_y][next_x]) continue;
        search_next.push_back(P(next_y, next_x));
        que.push(P(next_y, next_x));
        // que.push(make_tuple(next_y, next_x, curr_d+1));
        visited[next_y][next_x] = true;
      }
    }

  }
  int ans = bfs(current+1, search_next);
  return ans;
}
/***** MAIN *****/
signed main() {
  cin >> H >> W;
  cin >> c_y >> c_x; --c_y; --c_x;
  cin >> goal_y >> goal_x; --goal_y; --goal_x;
  REP(h, H) {
    REP(w, W) {
      char c;
      cin >> c;
      g[h][w] = (c == '.');
    }
  }
  cout << bfs(0);
  cout << "\n";
  return 0;
}
/***** MAIN *****/

Measured memory_bytes: 145324