#include <bits/stdc++.h>
#define fastIO() ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#define dpow(x) ((x) * (x))
#define abss(x) ((x) > 0 ? (x) : (-(x)))
#define in1(x) cin >> x
#define in2(x, y) cin >> x >> y
#define in3(x, y, z) cin >> x >> y >> z
#define in4(x, y, z, w) cin >> x >> y >> z >> w
#define rep(i, x, y) for (int i = x, a, b, c; i <= y; i++)
#define rep2(i, j, N, M) rep(i, 1, N) rep(j, 1, M)
#define repneq(i, x, y) for (int i = x, a, b, c; i < y; i++)
#define revrep(i, y, x) for (int i = y; i >= x; i--)
#define iterrep(item, items) for (auto item : items)
#define iterrefrep(item, items) for (auto &item : items)
#define EL cout << '\n'
#define endl '\n'
#define all(x) x.begin(), x.end()
#define ball(x, i) x.begin() + i, x.end()
#define PQ priority_queue
using namespace std;
int DX[] = {0, 1, 0, -1}, DY[] = {1, 0, -1, 0};
enum DIR { RIGHT, DOWN, LEFT, UP };
template <class T> int GetSign(T t) {
    if (t < 0)
        return -1;
    else if (t > 0)
        return 1;
    return 0;
}
inline int getSegSize(int N) { return 1 << ((int)ceil(log2(N)) + 1); }
template <class T> inline int getIdx(const vector<T> &v, T data) { return lower_bound(all(v), data) - v.begin(); }
template <class T> istream &operator>>(istream &stream, vector<T> &v) {
    repneq(i, 0, v.size()) stream >> v[i];
    return stream;
}
template <class T1, class T2> class Pair {
  public:
    T1 x;
    T2 y;
    Pair(T1 x_ = T1(), T2 y_ = T2()) : x(x_), y(y_) {}
    bool operator<(const Pair &p) const { return x == p.x ? y < p.y : x < p.x; }
    bool operator<=(const Pair &p) const { return x == p.x ? y <= p.y : x <= p.x; }
    bool operator>(const Pair &p) const { return x == p.x ? y > p.y : x > p.x; }
    bool operator!=(const Pair<T1, T2> &p) const { return x != p.x || y != p.y; }
    bool operator==(const Pair<T1, T2> &p) const { return x == p.x && y == p.y; }
    friend Pair<T1, T2> operator+(const Pair<T1, T2> &a, const Pair<T1, T2> &b) { return Pair<T1, T2>(a.x + b.x, a.y + b.y); }
    friend Pair<T1, T2> operator-(const Pair<T1, T2> &a, const Pair<T1, T2> &b) { return Pair<T1, T2>(a.x - b.x, a.y - b.y); }
    friend istream &operator>>(istream &stream, Pair &p) {
        stream >> p.x >> p.y;
        return stream;
    }
    friend ostream &operator<<(ostream &stream, const Pair &p) {
        stream << p.x << ' ' << p.y;
        return stream;
    }
};
template <class T> void printVector(const vector<T> &v, string sep = " ", string end = "\n") {
    if (v.empty()) return;
    for_each(v.begin(), v.end() - 1, [=](const T &a) { cout << a << sep; });
    cout << v[v.size() - 1] << end;
}
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LB;
typedef Pair<int, int> PII;
typedef Pair<LL, LL> PLL;
template <class X> using ADJGRAPH = vector<vector<X>>;
template <class T> T CCW(Pair<T, T> &a, Pair<T, T> &b, Pair<T, T> &c) { return (b.x - a.x) * (c.y - b.y) - (c.x - b.x) * (b.y - a.y); }
template <class T> T Factorial(T a) {
    T ret = 1;
    rep(i, 1, a) ret = ret * i;
    return ret;
}
template <class T> T Factorial(T a, T mod) {
    T ret = 1;
    rep(i, 1, a) ret = ret * i % mod;
    return ret;
}
bool CrossLine(vector<PLL> L1, vector<PLL> L2) {
    LL ccw1 = GetSign(CCW(L1[0], L1[1], L2[0])) * GetSign(CCW(L1[0], L1[1], L2[1]));
    LL ccw2 = GetSign(CCW(L2[0], L2[1], L1[0])) * GetSign(CCW(L2[0], L2[1], L1[1]));
    if (!ccw1 && !ccw2) {
        if (L1[0] > L1[1]) swap(L1[0], L1[1]);
        if (L2[0] > L2[1]) swap(L2[0], L2[1]);
        return (L1[0] <= L2[1] && L2[0] <= L1[1]);
    }
    return (ccw1 <= 0 && ccw2 <= 0);
}
namespace Constants {
const int MAXX = 1000;
const int MAXM = 0;
const int INF = 1 << 29;
const LL LINF = 1LL << 58;
const double PI = 3.1415926535;
const LL MOD = 1000000000LL;
}; // namespace Constants
//// ---------------------------- Solve Space
typedef Pair<int, PII> PIII;
int N, M;
PII S, E;
char Map[Constants::MAXX + 10][Constants::MAXX + 10];
int D[Constants::MAXX + 10][Constants::MAXX + 10];
int main() {
    fastIO();
    fill_n(&D[0][0], sizeof(D) / sizeof(int), Constants::INF);
    in2(N, M);
    in1(S);
    in1(E);
    rep(i, 2, N + 1) rep(j, 2, M + 1) in1(Map[i][j]), Map[i][j] = Map[i][j] != '#';
    PQ<PIII> Q;
    S.x++, S.y++, E.x++, E.y++;
    Q.push(PIII(0, S));
    D[S.x][S.y] = 0;
    while (!Q.empty()) {
        int c = -Q.top().x;
        int cx = Q.top().y.x, cy = Q.top().y.y;
        Q.pop();
        repneq(i, 0, 4) {
            int nx = cx + DX[i], ny = cy + DY[i];
            if (Map[nx][ny] == 0) continue;
            if (D[nx][ny] <= D[cx][cy]) continue;
            D[nx][ny] = D[cx][cy];
            Q.push(PIII(-D[nx][ny], PII(nx, ny)));
        }
        rep(i, -2, 2) rep(j, -2, 2) {
            int nx = cx + i, ny = cy + j;
            if (nx == cx && ny == cy) continue;
            if (Map[nx][ny] == 0) continue;
            if (D[nx][ny] <= D[cx][cy] + 1) continue;
            D[nx][ny] = D[cx][cy] + 1;
            Q.push(PIII(-D[nx][ny], PII(nx, ny)));
        }
    }
    cout << (D[E.x][E.y] == Constants::INF ? -1 : D[E.x][E.y]);
    return 0;
}

Measured memory_bytes: 8688