#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

// THINK: INT vs LONG LONG?

template <typename A, typename B>
string to_string(pair<A, B> p);
 
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);
 
string to_string(const string& s) {
    return '"' + s + '"';
}

string to_string(const char& c){
    string res;
    return "'" + res + c + "'";
}
 
string to_string(bool b) {
    return (b ? "True" : "False");
}

string to_string(vector<bool> v) {
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
        res += ", ";
      }
      first = false;
    res += to_string(v[i]);
    }
    res += "}";
    return res;
}
 
template <size_t N>
string to_string(bitset<N> v) {
    string res = "";
    for (size_t i = 0; i < N; i++) {
        res += static_cast<char>('0' + v[i]);
    }
    return res;
}
 
template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}
 
template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}
 
void debug_out() { cerr<<endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}
 
#ifdef LOCAL
#define debug(...) cerr << "\t[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else        
#define debug(...)
#endif  

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

    int h, w;
    cin >> h >> w;
    int srow, scol, drow, dcol;
    cin >> srow >> scol >> drow >> dcol;
    --srow, --scol, --drow, --dcol;
    vector<string> grid(h);
    for (int i = 0; i < h; ++i) {
        cin >> grid[i];
    }

    auto getID = [&](int row, int col){
        return row * w + col;
    };
    auto valid = [&](int row, int col){
        return row >= 0 && row < h && col >= 0 && col < w;
    };

    vector<vector<pair<int, int>>> adj(h * w);
    for (int row = 0; row < h; ++row){
        for (int col = 0; col < w; ++col){
            if (grid[row][col] == '#') continue;
            int u = getID(row, col);
            for (int i = -2; i <= 2; ++i){
                int nr = row + i;
                for (int j = -2; j <= 2; ++j){
                    int nc = col + j;
                    if (!valid(nr, nc) || (i == 0 && j == 0) || grid[nr][nc] == '#') continue;
                    int cost = 1;
                    if ((abs(i) == 1 && j == 0) || (abs(j) == 1 && i == 0)){
                        cost = 0;
                    }
                    adj[u].emplace_back(getID(nr, nc), cost);
                }
            }
        }
    }
    // cout << getID(1, 1) << endl;
    // debug(adj[4]);
    // for (auto )
    int dest = getID(drow, dcol);
    vector<int> dist(h * w, 1e9);
    vector<bool> vis(h * w);
    int start = getID(srow, scol);
    dist[start] = 0;
    deque<int> dq;
    dq.push_front(start);
    vis[start] = 1;
    while (!dq.empty()){
        int u = dq.front();
        dq.pop_front();
        for (auto edge: adj[u]){
            int v = edge.first, cost = edge.second;
            if (dist[u] + cost < dist[v]){
                dist[v] = dist[u] + cost;
                // if (v == 5){
                //     cout << u << " " << cost << endl;
                // }
                if (cost){
                    dq.push_back(v);
                }
                else {
                    dq.push_front(v);
                }
            }
            // vis[v] = 1;
        }
    }
    // cout << dist[5] << endl;
    if (dist[dest] == (int) 1e9) dist[dest] = -1;
    cout << dist[dest] << '\n';
    return 0;
}

Measured memory_bytes: 101680