#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <string>
#include <cstring>
#include <cctype>
#include <ctime>
#include <climits>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <tuple>
#include <bitset>
#include <cmath>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <numeric>
#include <complex>
#include <random>
#include <cassert>
#include <chrono>
#include <cstdint>
#include <functional>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#ifndef M_PI
#define M_PI 3.141592653589793238462643383279
#endif

#define mp make_pair
#define mt make_tuple
#define fr first
#define sc second
#define pb push_back
#define pp pop_back
#define all(x) x.begin(), x.end()
#define get0 get<0>
#define get1 get<1>
#define get2 get<2>
#define get3 get<3>

#define debug(x) cerr << #x << " = " << x << ", line = " << __LINE__ << endl

typedef long long ll;
typedef long double ld;
typedef tuple<long long, long long, long long> tlll;
typedef tuple<int, int, int> tiii;
typedef tuple<int, int, int, int> tiiii;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const int SZ = 1e3 + 100;
const int INF = 1e9 + 7;
char a[SZ][SZ];
int dist[SZ][SZ];
int h, w;

bool ok(int i, int j) {
    return 1 <= i && i <= h && 1 <= j && j <= w && a[i][j] == '.';
}

int32_t main()
{
#ifdef chikibambony
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#endif

    cin >> h >> w;
    int ch, cw, dh, dw;
    cin >> ch >> cw >> dh >> dw;
    for (int i = 0; i < SZ; ++i) {
        for (int j = 0; j < SZ; ++j) {
            dist[i][j] = INF;
        }
    }
    for (int i = 1; i <= h; ++i) {
        for (int j = 1; j <= w; ++j) {
            cin >> a[i][j];
        }
    }
    dist[ch][cw] = 0;
    deque<pii> q;
    q.push_front(mp(ch, cw));
    while (!q.empty()) {
        auto pr = q.front();
        q.pop_front();
        int i = pr.fr, j = pr.sc;
        if (ok(i - 1, j) && dist[i - 1][j] > dist[i][j]) {
            dist[i - 1][j] = dist[i][j];
            q.push_front(mp(i - 1, j));
        }
        if (ok(i + 1, j) && dist[i + 1][j] > dist[i][j]) {
            dist[i + 1][j] = dist[i][j];
            q.push_front(mp(i + 1, j));
        }
        if (ok(i, j - 1) && dist[i][j - 1] > dist[i][j]) {
            dist[i][j - 1] = dist[i][j];
            q.push_front(mp(i, j - 1));
        }
        if (ok(i, j + 1) && dist[i][j + 1] > dist[i][j]) {
            dist[i][j + 1] = dist[i][j];
            q.push_front(mp(i, j + 1));
        }
        for (int ik = -2; ik <= 2; ++ik) {
            for (int jk = -2; jk <= 2; ++jk) {
                if (ok(i + ik, j + jk) && dist[i + ik][j + jk] > dist[i][j] + 1) {
                    dist[i + ik][j + jk] = dist[i][j] + 1;
                    q.push_back(mp(i + ik, j + jk));
                }
            }
        }
    }
    if (dist[dh][dw] == INF) {
        cout << -1 << endl;
    } else {
        cout << dist[dh][dw] << endl;
    }
    return 0;
}


Measured memory_bytes: 9492