#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/stack:512000000")
#include<utility>
#include<iostream>
#include<fstream>
#include<vector>
#include<array>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<functional>
#include<random>
#include<climits>
#include<queue>
#include<stack>
#include<deque>
#include<bitset>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<cassert>
#include<ccomplex>
#include<chrono>

#ifdef ONLINE_JUDGE
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
#pragma GCC optimize("unroll-loops")
#define int128 __int128
#else
#define int128 long long
#endif

#define all(x) x.begin(), x.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define mp make_pair
#define X first
#define Y second

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
mt19937_64 gen(time(nullptr));

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

ll mod = 1e9 + 7;

namespace {
    ll mul(ll a, ll b) {
        ll val = a * b - (ll)((ld)a * b / mod) * mod;
        if (val < 0) val += mod;
        if (val >= mod) val -= mod;
        return val;
    }
    ll poww(ll a, ll b) {
        ll val = 1;
        a %= mod;
        while (b > 0) {
            if (b % 2) val = mul(a, val);
            a = mul(a, a);
            b >>= 1;
        }
        return val % mod;
    }
    ll inv(ll a) {
        return poww(a, mod - 2);
    }
}

ll const maxn = 3e5 + 5;
ll a[3005][3005];
ll d[3005][3005], used[3005][3005];

vector<ll> dx = { -1,0,1,0 };
vector<ll> dy = { 0, 1, 0, -1 };

ll n, m;

bool good(ll x, ll y) {
    return (x < n and x >= 0 and y < m and y >= 0 and !a[x][y]);
}

signed main() {
    ios_base::sync_with_stdio(0);cin.tie(0); cout.tie(0);
    cin >> n >> m;
    ll sx, sy; cin >> sx >> sy;
    ll tx, ty; cin >> tx >> ty;
    sx--, sy--, tx--, ty--;
    pair<ll, ll> s = { sx,sy };
    pair<ll, ll>t = { tx,ty };

    for (ll i = 0; i < n; i++) {
        for (ll j = 0; j < m; j++) {
            char c; cin >> c;
            a[i][j] = (c == '#');
            d[i][j] = 1e18;
        }
    }

    deque<pair<ll, ll>> q;
    q.push_front(s);
    d[s.X][s.Y] = 0;
    used[s.X][s.Y] = 1;

    while (!q.empty()) {
        auto p = q.front();
        q.pop_front();
        for (ll i = 0; i < 4; i++) {
            ll x = p.X + dx[i];
            ll y = p.Y + dy[i];
            pair<ll,ll> pp = { x, y };            
            if (good(x, y)) {
                if (d[x][y] > d[p.X][p.Y]) {
                    d[x][y] = d[p.X][p.Y];
                    q.push_front(pp);
                }
            }
        }
        for (ll x = p.X - 2; x <= p.X + 2; x++) {
            for (ll y = p.Y - 2; y <= p.Y + 2; y++) {
                if (good(x, y)) {
                    if (d[x][y] > d[p.X][p.Y]) {
                        d[x][y] = d[p.X][p.Y] + 1;
                        q.push_back({ x, y });
                    }
                }            
            }
        }   
    }
    if (!good(sx, sy)) {
        d[t.X][t.Y] = 1e18;
    }
    cout << (d[t.X][t.Y] == 1e18 ? -1 : d[t.X][t.Y]) << endl;


    return 0;
}

/*


*/

/*

*/

Measured memory_bytes: 28596