#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
const ll INF = 9e18;

void print() { cout << endl; }
template <typename Head, typename... Tail>
void print(Head head, Tail... tail) {
    int size = sizeof...(Tail);
    cout << head;
    if (size > 0) {
        cout << " ";
    }
    print(tail...);
}

int main() {
    ll H, W;
    cin >> H >> W;
    ll sh, sw, gh, gw;
    cin >> sh >> sw;
    cin >> gh >> gw;
    sh--;
    sw--;
    gh--;
    gw--;

    // 道の一覧
    set<pair<ll, ll>> roads;
    for (ll h = 0; h < H; h++) {
        for (ll w = 0; w < W; w++) {
            char c;
            cin >> c;
            while (c != '.' && c != '#') {
                cin >> c;
            }
            if (c == '.') {
                roads.insert(make_pair(h, w));
            }
        }
    }

    // dfs. 道にIDを割り振る
    ll union_id = 0;
    vector<vector<ll>> union_map(H, vector<ll>(W, -1));
    while (!roads.empty()) {
        stack<pair<ll, ll>> search;
        search.push(*roads.begin());
        while (!search.empty()) {
            auto p = search.top();
            search.pop();
            roads.erase(p);
            union_map[p.first][p.second] = union_id;

            auto top = make_pair(p.first - 1, p.second);
            if (roads.count(top) > 0) {
                search.push(top);
            }
            auto right = make_pair(p.first, p.second + 1);
            if (roads.count(right) > 0) {
                search.push(right);
            }
            auto bottom = make_pair(p.first + 1, p.second);
            if (roads.count(bottom) > 0) {
                search.push(bottom);
            }
            auto left = make_pair(p.first, p.second - 1);
            if (roads.count(left) > 0) {
                search.push(left);
            }
        }
        union_id++;
    }

    // 異なるIDのunion間の隣接
    set<pair<ll, ll>> edgeset;
    for (ll h = 0; h < H; h++) {
        for (ll w = 0; w < W; w++) {
            // 25倍。ちょっと重い。 (10^6*25)
            ll u = union_map[h][w];
            if (u < 0) {
                continue;
            }
            for (ll y = h - 2; y <= h + 2; y++) {
                for (ll x = w - 2; x <= w + 2; x++) {
                    if (y >= 0 && y < H && x >= 0 && x < W && union_map[y][x] >= 0 && union_map[y][x] != u) {
                        ll v = union_map[y][x];
                        edgeset.insert(make_pair(u, v));
                        edgeset.insert(make_pair(v, u));
                    }
                }
            }
        }
    }
    vector<vector<ll>> edgemap(union_id + 1);
    for (auto edg : edgeset) {
        ll u = edg.first;
        ll v = edg.second;
        edgemap[u].push_back(v);
        edgemap[v].push_back(u);
    }

    // unionの距離
    vector<ll> union_dist(union_id + 1, -1);
    queue<ll> edgsearch;
    edgsearch.push(union_map[sh][sw]);
    union_dist[union_map[sh][sw]] = 0;
    while (!edgsearch.empty()) {
        ll usrc = edgsearch.front();
        edgsearch.pop();
        for (ll udest : edgemap[usrc]) {
            if (union_dist[udest] == -1) {
                union_dist[udest] = union_dist[usrc] + 1;
                edgsearch.push(udest);
            }
        }
    }

    print(union_dist[union_map[gh][gw]]);
}


Measured memory_bytes: 49020