#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
using ll = long long;
#define int ll
using pii = pair<int, int>;
using tiii = tuple<int, int, int>;
template<class T = ll> using V = vector<T>;
template<class T = ll> using VV = V<V<T>>;
#define IOS\
    ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
#define FOR(i,l,r) for(ll i=(l);i<(r);++i)
#define REP(i,n) FOR(i,0,n)
#define REPS(i,n) FOR(i,1,n+1)
#define RFOR(i,l,r) for(ll i=(l);i>=(r);--i)
#define RREP(i,n) RFOR(i,n-1,0)
#define RREPS(i,n) RFOR(i,n,1)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define SORT(name) sort(name.begin(), name.end())
#define RSORT(name)\
    SORT(name);\
    reverse(all(name));
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
inline void Yes(bool b = true) {cout << (b ? "Yes" : "No") << '\n';}
inline void YES(bool b = true) {cout << (b ? "YES" : "NO") << '\n';}
template <class T> inline void print(T x){ cout << x << '\n';}
template<typename T1,typename T2> inline void chmin(T1 &a, T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a, T2 b){ if(a < b) a = b; }

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
#pragma endregion

#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const int MOD = 1000000007;
const int MAX_N = 100010;

int Ch, Cw, Dh, Dw;
int H, W;
V<string> S;

V< V<> > dist;

// (y, x) へ cur で進む場合の処理
void AddDequeFront(deque<pii>& q, int y, int x, int cur) {
    if(dist[y][x] <= cur) { return; }
    if(S[y][x] == '#') { return; }
    dist[y][x] = cur;
    q.emplace_front(mp(y, x));
}
void AddDequeBack(deque<pii>& q, int y, int x, int cur) {
    if(dist[y][x] <= cur) { return; }
    if(S[y][x] == '#') { return; }
    dist[y][x] = cur;
    q.emplace_back(mp(y, x));
}

signed main() {
    IOS;

    cin >> H >> W;
    cin >> Ch >> Cw;
    cin >> Dh >> Dw;
    Ch--; Cw--; Dh--; Dw--;

    S.resize(H);
    REP(i, H) {
        cin >> S[i];
    }

    dist.assign(H, V<>(W, LLINF));
    deque<pii> q;

    // 01-BFS
    // 始点から始めて、同距離で行けるなら頭に入れる。
    // ワープするなら後ろに入れる。
    q.emplace_front(mp(Ch, Cw));
    dist[Ch][Cw] = 0;
    while(!q.empty()) {
        auto node = q.front();
        q.pop_front();
        int y = node.first;
        int x = node.second;
        int cur = dist[y][x];
        // 上下左右へ進む
        if(y > 0) {
            AddDequeFront(q, y - 1, x, cur);
        }
        if(y < H - 1) {
            AddDequeFront(q, y + 1, x, cur);
        }
        if(x > 0) {
            AddDequeFront(q, y, x - 1, cur);
        }
        if(x < W - 1) {
            AddDequeFront(q, y, x + 1, cur);
        }
        // ワープでいけるところを追加
        for(int i = y - 2; i <= y + 2; ++i) {
            if(i < 0 || i >= H) { continue; }
            for(int j = x - 2; j <= x + 2; ++j) {
                if(j < 0 || j >= W) { continue; }
                AddDequeBack(q, i, j, cur + 1);
            }
        }
    }
    if(dist[Dh][Dw] >= LLINF) {
        print(-1);
        return 0;
    }
    print(dist[Dh][Dw]);

    return 0;
}


Measured memory_bytes: 12640