#include <bits/stdc++.h>
#include <ext/rope>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define ll long long
#define int long long
#define pb push_back
#define x first
#define ld long double
#define y second
#define mk(a,b) make_pair(a,b)
#define rr return 0
#define sqr(a) ((a)*(a))
#define all(a) a.begin(),a.end()

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
template<class value, class cmp = less<value> >
using ordered_set = tree<value, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template<class value, class cmp = less_equal<value> >
using ordered_multiset = tree<value, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template<class key, class value, class cmp = less<key> >
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;

/// find_by_order()
/// order_of_key()
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int randll(int l = INT_MIN, int r = INT_MAX) {
    return uniform_int_distribution<int>(l, r)(rng);
}

main()
{
    ios::sync_with_stdio(0);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
//    int n, x, t;
//    cin >> n >> x >> t;
//    cout << ((n + x - 1) / x) * t << '\n';


//    string s;
//    cin >> s;
//    int sum = 0;
//    for (auto &i : s) sum += i - '0';
//    if (sum % 9 == 0) {
//        cout << "Yes\n";
//    }
//    else cout << "No\n";


//    int n, ans = 0, last = 0;
//    cin >> n;
//    cin >> last;
//    int x;
//    for (int i = 1; i < n; i++) {
//        cin >> x;
//        ans += max(0ll, last - x);
//        last = max(last, x);
//    }
//    cout << ans << '\n';

    int n, m;
    cin >> n >> m;
    int x, y, x0, y0;
    cin >> x >> y;
    cin >> x0 >> y0;
    --x, --y, --x0, --y0;
    vector <string> a(n);
    for (auto &i : a) cin >> i;
    const int INF = 1e9;
    vector <vector <int> > d(n, vector <int> (m, INF));
    d[x][y] = 0;
    deque <pair<int, int> > q;
    q.pb({x, y});
    while (!q.empty()) {
        tie(x, y) = q.front();
        q.pop_front();
        int dx[] = {0, 0, -1, 1};
        int dy[] = {-1, 1, 0, 0};
        for (int i = 0; i < 4; i++) {
            int tox = x + dx[i];
            int toy = y + dy[i];
            if (tox < 0 || toy < 0 || tox >= n || toy >= m) continue;
            if (a[tox][toy] == '#') continue;
            if (d[tox][toy] > d[x][y]) {
                d[tox][toy] = d[x][y];
                q.push_front({tox, toy});
            }
        }
        for (int i = -2; i <= 2; i++) {
            for (int j = -2; j <= 2; j++) {
                int tox = x + i;
                int toy = y + j;
                if (tox < 0 || toy < 0 || tox >= n || toy >= m) continue;
                if (a[tox][toy] == '#') continue;
                if (d[tox][toy] > d[x][y] + 1) {
                    d[tox][toy] = d[x][y] + 1;
                    q.pb({tox, toy});
                }
            }
        }
    }
    if (d[x0][y0] >= INF) cout << -1;
    else
    cout << d[x0][y0] << '\n';

//    int n, m, k, x, y;
//    cin >> n >> m >> k;
//    vector <int> cnt1(n), cnt2(m);
//    map <pair<int, int>, int> have;
//    map <int, vector <int> > nice;
//    for (int i = 0; i < k; i++) {
//        cin >> x >> y;
//        --x, --y;
//        ++cnt1[x];
//        ++cnt2[y];
//        ++have[{x, y}];
//        nice[x].pb(y);
//    }
//    vector <pair<int, int> > c(m);
//    for (int i = 0; i < m; i++) {
//        c[i] = {cnt2[i], i};
//    }
//    sort(all(c));
//    reverse(all(c));
//    int ans = 0;
//    for (int i = 0; i < n; i++) {
//        int res = cnt1[i];
//        set <int> cur;
//        for (auto &j : nice[i]) {
//            cur.insert(j);
//            res = max(res, cnt1[i] + cnt2[j] - 1);
//        }
//        for (int  j = 0; j < m; j++) {
//            if (!cur.count (c[j].y)) {
//                res = max(res, cnt1[i] + cnt2[c[j].y]);
//                break;
//            }
//        }
//        ans = max(ans, res);
//    }
//    cout << ans << '\n';



}


Measured memory_bytes: 12720