//  [cpp]
#include <bits/stdc++.h>

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using usize = std::size_t;
using namespace std;

#define rep(i, max) for(i32 i = 0; i < (i32)max; ++i)
#define loop while(true)
#define allOf(collection) collection.begin(), collection.end()

unique_ptr<string> readLine() { unique_ptr<string> line(new string()); getline(cin, *line); return line; }
template<typename T1, typename T2> pair<T1, T2> readPair() { T1 res1; cin >> res1; T2 res2; cin >> res2; readLine(); return make_pair(res1, res2);}
template<typename T> unique_ptr<vector<T>> readVector(usize num) { unique_ptr<vector<T>> list(new vector<T>(num)); rep(i, num) cin >> (*list)[i]; readLine(); return list; }
void readValues() { readLine(); }
template<typename H, typename... T> void readValues(H& head, T&&... tails){ H a; cin >> a; head = a; readValues(forward<T>(tails)...); }
void writeLine() { cout << endl; }
template<typename T> void write(const T& arg) { cout << arg; }
template<typename T> void writeLine(const vector<T>& arg){ if(arg.empty()) { writeLine(); return; } write(arg[0]); for(int i = 1; i < arg.size(); ++i){ write(" "); write(arg[i]); } writeLine(); }
template<typename T> void writeLine(const T& arg) { cout << arg << endl; }
void recursiveCombination(vector<i32>& indexes, i32 s, i32 rest, function<void(vector<i32>&)> f) { if (rest == 0) { f(indexes); } else { if (s < 0) return; recursiveCombination(indexes, s - 1, rest, f); indexes[rest - 1] = s; recursiveCombination(indexes, s - 1, rest - 1, f); } }
void foreachWithCombination(i32 n, i32 k, function<void(vector<i32>&)> f) { auto indexes = vector<i32>(k); recursiveCombination(indexes, n - 1, k, f); }
void foreachWithPermutaton(i32 n, function<void(vector<i32>&)> f) { auto indexes = vector<i32>(); indexes.reserve(n); rep(i, (usize)n) indexes.push_back(i); do f(indexes); while (next_permutation(allOf(indexes))); }
void foreachWithPermutaton(i32 n, i32 k, function<void(vector<i32>&)> f){ foreachWithCombination(n, k, [=](vector<i32>& combIndexes){ foreachWithPermutaton(k, [=](vector<i32>& permIndexes){ auto indexes = vector<i32>(); indexes.reserve(k); rep(i, (usize)k){ indexes.push_back(combIndexes[permIndexes[i]]); } f(indexes); }); }); }
void program();
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    program();
}

struct Info {
    i32 h, w;
    Info(i32 h_, i32 w_){
        h = h_;
        w = w_;
    }
};

void program() {
    i32 h, w, cH, cW, dH, dW;
    readValues(h, w, cH, cW, dH, dW);
    auto s = vector<string>();
    rep(i, h){
        s.push_back(*readLine());
    }

    auto que = queue<Info>();
    s[cH - 1][cW - 1] = 'd';
    que.emplace(cH - 1, cW - 1);
    auto list = vector<set<Info>>();
    int warpCount = 0;
    bool goaled = false;
    auto newPoints = vector<Info>();
    newPoints.emplace_back(cH - 1, cW - 1);
    loop{
        auto alSet = vector<Info>();
        for(const auto& item: newPoints) {
            alSet.push_back(item);
        }
        
        while(!que.empty()){
            auto info = que.front();
            que.pop();

            if(info.h == dH - 1 && info.w == dW - 1) {
                goaled = true;
                goto exit5;
            }

            if(info.h + 1 < h && s[info.h + 1][info.w] == '.'){
                s[info.h + 1][info.w] = 'd';
                alSet.emplace_back(info.h + 1, info.w);
                que.emplace(info.h + 1, info.w);
            }
            if(0 <= info.h - 1 && s[info.h - 1][info.w] == '.'){
                s[info.h - 1][info.w] = 'd';
                alSet.emplace_back(info.h - 1, info.w);
                que.emplace(info.h - 1, info.w);
            }
            if(info.w + 1 < w && s[info.h][info.w + 1] == '.'){
                s[info.h][info.w + 1] = 'd';
                alSet.emplace_back(info.h, info.w + 1);
                que.emplace(info.h, info.w + 1);
            }
            if(0 <= info.w - 1 && s[info.h][info.w - 1] == '.'){
                s[info.h][info.w - 1] = 'd';
                alSet.emplace_back(info.h, info.w - 1);
                que.emplace(info.h, info.w - 1);
            }
        }
        newPoints.clear();
        for(const auto& item: alSet){
            for(i32 i = max(0, item.h - 2); i <= min(h - 1, item.h + 2); ++i){
                for(i32 j = max(0, item.w - 2); j <= min(w - 1, item.w + 2); ++j){
                    if(s[i][j] == '.') {
                        s[i][j] = 'd';
                        que.emplace(i, j);
                        newPoints.emplace_back(i, j);
                    }
                }
            }
        }
        if(newPoints.size() == 0) goto exit5;
        ++warpCount;
    }
    exit5:
    
    writeLine(goaled ? warpCount : -1);
}