#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define rep2(i, s, n) for (ll i = (s); i < (ll)(n); i++)
const ll MAX = 1001001;
const ll MOD = 1000000007;
struct edge
{
    ll to, cost;
};
typedef vector<vector<edge>> AdjList;
AdjList graph;
const ll INF = 1001001001001001001;
vector<ll> dist, prever;
void dijkstra(ll n, ll s)
{
    dist = vector<ll>(n, INF);
    prever = vector<ll>(n, -1);
    dist[s] = 0;
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P(0, s));
    while (que.size())
    {
        P p = que.top();
        que.pop();
        ll v = p.second;
        if (dist[v] < p.first)
        {
            continue;
        }
        for (ll i = 0; i < graph[v].size(); i++)
        {
            edge e = graph[v][i];
            if (dist[e.to] > dist[v] + e.cost)
            {
                dist[e.to] = dist[v] + e.cost;
                prever[e.to] = v;
                que.push(P(dist[e.to], e.to));
            }
        }
    }
}

vector<ll> get_path(ll t)
{ //頂点への最短路
    vector<ll> path;
    for (; t != -1; t = prever[t])
    {
        path.push_back(t);
    }
    reverse(path.begin(), path.end());
    return path;
}
/*
graph=AdjList(n);
rep(i,n-1){
  ll from,to,cost;
  ll cin>>from>>to>>cost;
  from--;to--;
  graph[from].push_back((edge){to,cost});
  graph[to].push_back((edge){from,cost});
}
*/
int main()
{
    ll h, w;
    cin >> h >> w;
    ll cx, cy, gx, gy;
    cin >> cx >> cy >> gx >> gy;
    cx--;
    cy--;
    gx--;
    gy--;
    graph = AdjList(h * w);
    vector<vector<char>> s(h, vector<char>(w));
    rep(i, h)
    {
        rep(j, w)
        {
            cin >> s[i][j];
        }
    }
    ll dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
    rep(i, h)
    {
        rep(j, w)
        {
            rep(k, 4)
            {
                if (s[i][j] == '#')
                {
                    continue;
                }
                ll nx = i + dx[k];
                ll ny = j + dy[k];
                if (0 <= nx && nx < h && 0 <= ny && ny < w)
                {
                    if (s[nx][ny] == '.')
                    {
                        graph[i * w + j].push_back((edge){nx * w + ny, 0});
                        graph[nx * w + ny].push_back((edge){i * w + j, 0});
                    }
                }
                rep2(k, -2, 3)
                {
                    rep2(l, -2, 3)
                    {
                        if (abs(k) + abs(l) < 2)
                        {
                            continue;
                        }
                        ll nx = i + k;
                        ll ny = j + l;
                        if (0 <= nx && nx < h && 0 <= ny && ny < w && s[nx][ny] != '#')
                        {
                            graph[i * w + j].push_back((edge){nx * w + ny, 1});
                            graph[nx * w + ny].push_back((edge){i * w + j, 1});
                        }
                    }
                }
            }
        }
    }
    dijkstra(h * w, cx * w + cy);
    if (dist[gx * w + gy] == INF)
    {
        cout << -1 << endl;
    }
    else
    {
        cout << dist[gx * w + gy] << endl;
    }
}

Measured memory_bytes: 983692