#include <bits/stdc++.h>
using namespace std;
using ll         = long long;
constexpr ll MOD = 1000000007;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, x, n) for (ll i = x; i < (n); i++)
const long long INF = numeric_limits<long long>::max();
template <class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
vector<ll> getNums(ll N) {
    vector<ll> num(N);
    REP(i, N) {
        cin >> num[i];
    }
    return num;
}

struct Position {
    ll x;
    ll y;

    bool Within(ll x, ll y) const {
        if (this->x < 0) return false;
        if (this->y < 0) return false;
        if (this->x >= x) return false;
        if (this->y >= y) return false;
        return true;
    }

    friend Position operator+(const Position& lhs, const Position& rhs) {
        return Position{lhs.x + rhs.x, lhs.y + rhs.y};
    }

    friend ostream& operator<<(ostream& os, const Position& pos) {
#ifdef SOURCE_TEST
        os << pos.x << "," << pos.y;
#endif
        return os;
    }

    template <class TData> TData& GetValueFrom(vector<vector<TData>>& vec) const {
        return vec[x][y];
    }

    char& GetValueFrom(vector<string>& vec) const {
        return vec[x][y];
    }
};
vector<string> field;
Position start;
Position goal;
ll H, W;

void debugMap() {
#ifdef SOURCE_TEST

    cout << "mapList" << endl;
    for (ll i = 0; i < field.size(); ++i) {
        for (ll j = 0; j < field[i].length(); ++j) {
            if (i == start.x && j == start.y) {
                cout << 'S';
            } else if (i == goal.x && j == goal.y) {
                cout << 'G';
            } else {
                cout << field[i][j];
            }
        }
        cout << endl;
    }
#endif
}

vector<vector<ll>> warpList;
void debugWarp() {
#ifdef SOURCE_TEST

    cout << "warpList" << endl;
    for (ll i = 0; i < warpList.size(); ++i) {
        for (ll j = 0; j < warpList[i].size(); ++j) {
            cout << std::setw(2) << warpList[i][j];
        }
        cout << endl;
    }
#endif
}

bool isOverOk(const Position& pos, ll value) {
    return pos.GetValueFrom(warpList) == -1;
}
void setWalking(const Position& pos, ll value);
void setWarpValue(const Position& pos, ll value) {
    for (ll i = -2; i <= 2; ++i) {
        for (ll j = -2; j <= 2; ++j) {
            if (i == 0 && j == 0) continue;

            Position p = pos + Position{i, j};
            if (!p.Within(H, W)) continue;
            if (p.GetValueFrom(field) == '#') continue;
            if (isOverOk(p, value)) {
                p.GetValueFrom(warpList) = value;
            }
        }
    }
#ifdef SOURCE_TEST
    cout << "setWarpCase" << value << "-----" << endl;
#endif
    debugWarp();
}
void setWalkValue(const Position& pos, ll value) {
    if (!pos.Within(H, W)) return;
    if (pos.GetValueFrom(field) != '#' && isOverOk(pos, value)) {
        pos.GetValueFrom(warpList) = value;
        setWalking(pos, value);
    }
}
void setWalking(const Position& pos, ll value) {
    setWalkValue({pos.x + 1, pos.y}, value);
    setWalkValue({pos.x - 1, pos.y}, value);
    setWalkValue({pos.x, pos.y + 1}, value);
    setWalkValue({pos.x, pos.y - 1}, value);
}

void funcWalk(const Position& pos, ll value) {
    setWalking(pos, value);
#ifdef SOURCE_TEST
    cout << "setWalkEnd" << value << "-----" << endl;
    debugWarp();
#endif

    for (ll i = 0; i < H; ++i) {
        for (ll j = 0; j < W; ++j) {
            if (warpList[i][j] == value) {
                setWarpValue({i, j}, value + 1);
            }
        }
    }

#ifdef SOURCE_TEST
    cout << "warped-----" << endl;
#endif

    for (ll i = 0; i < H; ++i) {
        for (ll j = 0; j < W; ++j) {
            Position pos{i, j};
            if (!pos.Within(H, W)) continue;
            if (warpList[i][j] == value + 1) {
                funcWalk({i, j}, value + 1);
            }
        }
    }
}

int main() {
    cin >> H >> W;

    cin >> start.x >> start.y;
    start.x--;
    start.y--;
    cin >> goal.x >> goal.y;
    goal.x--;
    goal.y--;

    field.resize(H);
    warpList.resize(H);
    for (ll i = 0; i < H; ++i) {
        cin >> field[i];
        warpList[i] = vector<ll>(W, -1);
    }
    start.GetValueFrom(warpList) = 0;

    debugMap();
    debugWarp();

    // funcWalk(start, 0);

    {
        deque<pair<Position, ll>> queues;
        queues.push_back({start, 0});
        while (!queues.empty()) {
            ll thisValue = queues.front().second;
            vector<Position> setPositions;
            while (!queues.empty()) {
                auto v = queues.front();
                queues.pop_front();
                setPositions.push_back(v.first);
                vector<Position> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
                for (const auto d : directions) {
                    auto pos = v.first + d;
                    if (pos.Within(H, W) && pos.GetValueFrom(field) != '#') {
                        auto& value = pos.GetValueFrom(warpList);

                        if (value == -1 || value > v.second) {
                            value = v.second;
                            setPositions.push_back(pos);
                            queues.push_front({pos, v.second});
                        }
                    }
                }
                debugWarp();
            }

            ll nextValue = thisValue + 1;
            for (auto position : setPositions) {
                for (ll i = -2; i <= 2; ++i) {
                    for (ll j = -2; j <= 2; ++j) {
                        auto p = position + Position{i, j};
                        if (!p.Within(H, W)) continue;
                        if (p.GetValueFrom(field) == '#') continue;
                        auto& v = p.GetValueFrom(warpList);
                        if (v == -1 || v > nextValue) {
                            v = nextValue;
                            queues.push_back({p, nextValue});
                        }
                    }
                }
            }
        }
    }
#ifdef SOURCE_TEST
    cout << "before ans-----" << endl;
#endif
    debugWarp();

    cout << goal.GetValueFrom(warpList) << endl;

    return 0;
}

Measured memory_bytes: 13968