#include <stack>
#include <queue>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <tuple>
#include <cmath>
#include <random>
#include <algorithm>
#include <vector>
#include <iostream>
#include <fstream>
#include <chrono>
#include <numeric>

#define fio ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
#define rng mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count())

#define ri(...) i64 __VA_ARGS__; rx(__VA_ARGS__)
#define rc(...) char __VA_ARGS__; rx(__VA_ARGS__)
#define rs(...) string __VA_ARGS__; rx(__VA_ARGS__)
#define rvi(x, n) vi x(n); cin >> x
#define rvvi(x, n, m) vvi x(n, vi(m)); cin >> x

#ifndef ONLINE_JUDGE
#define dbg(...) cerr << '[' << #__VA_ARGS__ << "]: "; dbg_log(__VA_ARGS__)
#else
#define dbg(...) ;;
#endif

#define fa(i, v) for (auto &i : v)
#define fi(i, n) for (i32 i = 0; i < n; i++)
#define fp(i, n) for (i32 i = 1; i < n; i++)
#define fr(i, n) for (i32 i = n - 1; i >= 0; i--)
#define fu(i) ri(_i); fi(i, _i)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

using namespace std;

typedef uint32_t u32;
typedef int32_t i32;
typedef uint64_t u64;
typedef int64_t i64;
#ifdef __SIZEOF_INT128__
typedef __uint128_t u128;
typedef __int128_t i128;
#endif
typedef vector<i64> vi;
typedef vector<vi> vvi;

template<typename T>
inline istream &operator>>(istream &in, vector<T> &v) {
    fa(x, v) in >> x;
    return in;
}

template<typename T>
inline ostream &operator<<(ostream &out, const vector<T> &v) {
    fa(x, v) out << x << ' ';
    return out;
}

template<typename T>
inline void rx(T &x) {
    cin >> x;
}

template<typename T, typename... R>
inline void rx(T &x, R &... l) {
    cin >> x;
    rx(l...);
}

template<typename T>
inline void dbg_log(const T &x) {
    cerr << x << '\n';
}

template<typename T, typename... R>
inline void dbg_log(const T &x, const R &... l) {
    cerr << x << ", ";
    dbg_log(l...);
}

template<typename T>
inline void wl(const T &x) {
    cout << x << '\n';
}

template<typename T, typename... R>
inline void wl(const T &x, const R &... l) {
    cout << x << ' ';
    wl<R...>(l...);
}

int main() {
    fio;

    ri(n, m);
    ri(sx, sy, fx, fy);
    vector<string> s(n);
    fa(x, s) rx(x);

    vector<vector<i32>> c(n, vector<i32>(m, -1));
    auto dfs = [&](auto &&dfs, i32 i, i32 j, i32 k) -> bool {
        if (i < 0 || i >= n || j < 0 || j >= m || s[i][j] != '.') return false;
        s[i][j] = 'x';
        c[i][j] = k;
        dfs(dfs, i - 1, j, k);
        dfs(dfs, i, j - 1, k);
        dfs(dfs, i + 1, j, k);
        dfs(dfs, i, j + 1, k);
        return true;
    };
    i32 k = 0;
    fi(i, n) {
        fi(j, m) {
            if (dfs(dfs, i, j, k)) k++;
        }
    }

    vector<set<i32>> adj(k);
    auto add = [&](i32 i, i32 j, i32 x, i32 y) {
        if (x < 0 || x >= n || y < 0 || y >= m || c[i][j] < 0 || c[x][y] < 0 || c[i][j] == c[x][y]) return;
        adj[c[i][j]].insert(c[x][y]);
        adj[c[x][y]].insert(c[i][j]);
    };
    fi(i, n) {
        fi(j, m) {
            add(i, j, i - 1, j + 1);
            add(i, j, i + 1, j + 1);
            add(i, j, i + 1, j - 2);
            add(i, j, i + 2, j - 2);
            add(i, j, i + 2, j - 1);
            add(i, j, i + 2, j);
            add(i, j, i + 2, j + 1);
            add(i, j, i + 2, j + 2);
            add(i, j, i + 1, j + 2);
            add(i, j, i, j + 2);
        }
    }

    i32 start = c[sx - 1][sy - 1];
    i32 finish = c[fx - 1][fy - 1];

    vector<bool> v(k);
    queue<pair<i32, i32>> q;
    q.emplace(0, start);
    while (!q.empty()) {
        auto[l, x]=q.front();
        q.pop();
        if (v[x]) continue;
        v[x] = true;
        if (x == finish) {
            wl(l);
            return 0;
        }
        fa(y, adj[x]) {
            q.emplace(l + 1, y);
        }
    }
    wl(-1);

    return 0;
}


Measured memory_bytes: 32424