#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#include <climits>

#define CLOOP        while (true)
#define FLOOP(i, n)  for (int i = 0; i < (n); i++)
#define FOR(i, f, l) for (int i = (f); i < (l); i++)
#ifdef DEBUG
#define DUMP(var)   cerr << "[DEBUG] " << #var << ": " << var << endl
#else
#define DUMP(var)
#endif

#define LL long long

using namespace std;

static inline void dfs01_push(pair<int, int> node, deque<pair<int, int>>& dfsq, int cost)
{
    if (!cost) {
        dfsq.push_front(make_pair(node.first, node.second));
    }
    else {
        dfsq.push_back(make_pair(node.first, node.second));
    }
}

static int dfs01(pair<int, int> node,
                 int hh,
                 int ww,
                 char s[][1000],
                 int dist[][1000],
                 deque<pair<int, int>>& dfsq,
                 pair<int, int> end)
{
    int h, w;

    if (node.first == end.first && node.second == end.second)
        return dist[node.first][node.second];

    FOR(i, -2, 0) {
        FOR(j, -2, 3) {
            h = node.first+i;
            w = node.second+j;
            if (0 <= h && h < hh && 0 <= w && w < ww && s[h][w] == '.') {
                    if (i == -1 && j == 0 && dist[node.first][node.second] < dist[h][w]) {
                        dist[h][w] = dist[node.first][node.second];
                        dfs01_push(make_pair(h, w), dfsq, 0);
                    } else if (dist[node.first][node.second]+1 < dist[h][w]) {
                        dist[h][w] = dist[node.first][node.second] + 1;
                        dfs01_push(make_pair(h, w), dfsq, 1);
                    }
            }
        }
    }

    FOR(i, -2, 0) {
        h = node.first;
        w = node.second+i;
        if (0 <= h && h < hh && 0 <= w && w < ww && s[h][w] == '.') {
            if (i == -1 && dist[node.first][node.second] < dist[h][w]) {
                dist[h][w] = dist[node.first][node.second];
                dfs01_push(make_pair(h, w), dfsq, 0);
            }
            else if (dist[node.first][node.second]+1 < dist[h][w]) {
                dist[h][w] = dist[node.first][node.second] + 1;
                dfs01_push(make_pair(h, w), dfsq, 1);
            }
        }
    }

    FOR(i, 1, 3) {
        h = node.first;
        w = node.second+i;
        if (0 <= h && h < hh && 0 <= w && w < ww && s[h][w] == '.') {
            if (i == 1 && dist[node.first][node.second] < dist[h][w]) {
                dist[h][w] = dist[node.first][node.second];
                dfs01_push(make_pair(h, w), dfsq, 0);
            } else if (dist[node.first][node.second]+1 < dist[h][w]) {
                dist[h][w] = dist[node.first][node.second] + 1;
                dfs01_push(make_pair(h, w), dfsq, 1);
            }
        }
    }

    FOR(i, 1, 3) {
        FOR(j, -2, 3) {
            h = node.first+i;
            w = node.second+j;
            if (0 <= h && h < hh && 0 <= w && w < ww && s[h][w] == '.') {
                if (i == 1 && j == 0 && dist[node.first][node.second] < dist[h][w]) {
                    dist[h][w] = dist[node.first][node.second];
                    dfs01_push(make_pair(h, w), dfsq, 0);
                } else if (dist[node.first][node.second]+1 < dist[h][w]) {
                    dist[h][w] = dist[node.first][node.second] + 1;
                    dfs01_push(make_pair(h, w), dfsq, 1);
                }
            }
        }
    }

    return -1;
}

int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int h, w, ch, cw, dh, dw;
    cin >> h >> w >> ch >> cw >> dh >> dw;
    char s[1000][1000];
    FLOOP(i, h) FLOOP(j, w) cin >> s[i][j];

    int dist[1000][1000], ddist;
    deque<pair<int, int>> dfsq;
    pair<int, int> start = make_pair(ch-1, cw-1), end = make_pair(dh-1, dw-1), p;
    dfsq.push_front(start);
    fill(dist[0], dist[h], INT_MAX);
    dist[start.first][start.second] = 0;
    while (!dfsq.empty()) {
        p = dfsq.front();
        dfsq.pop_front();
        ddist = dfs01(p, h, w, s, dist, dfsq, end);
        if (ddist != -1) {
            cout << ddist << endl;
            return 0;
        }
    }

    cout << -1 << endl;
    return 0;
}


Measured memory_bytes: 8588