#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define loop(i,a,b) for (int i=a; i<b; ++i)

void process(queue < pair<int, int> > &Q, vector < vector <bool> > &visited, vector < vector <int> > &component, int curcomponent, int H, int W, int i, int j, vector <  string > &grid)
{
    if (i<0 || j<0) return;
    if (i>=H || j>=W) return;
    if (visited[i][j]) return;
    if (grid[i][j]=='#') return;
    Q.push({i,j});
    component[i][j]=curcomponent;
    visited[i][j]=true;
}


int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll H,W;
    cin >> H >> W;
    pair <ll, ll> start,end;
    cin >> start.first >> start.second;
    cin >> end.first >> end.second;
    vector <  string > grid(H);
    loop(i,0,H) cin >> grid[i];
    vector < vector <bool> > visited(H, vector <bool>(W,false));
    vector < vector <int> > component(H, vector<int>(W,-1));
    int curcomponent=-1;
    for (int i=0; i<H; ++i)
    {
        for (int j=0; j<W; ++j)
        {
            if (grid[i][j]=='#') continue;
            if (visited[i][j]) continue;
            visited[i][j]=true;
            curcomponent++;
            component[i][j]=curcomponent;
            // cout << i << " " << j << " " << curcomponent << "\n";
            queue < pair<int, int> > Q;
            Q.push({i,j});
            while (!Q.empty())
            {
                int cx=Q.front().first, cy=Q.front().second;
                Q.pop();
                process(Q, visited, component, curcomponent, H, W, cx-1, cy, grid);
                process(Q, visited, component, curcomponent, H, W, cx, cy-1, grid);
                process(Q, visited, component, curcomponent, H, W, cx+1, cy, grid);
                process(Q, visited, component, curcomponent, H, W, cx, cy+1, grid);
            } 
        }
    }
    // cout << curcomponent << "\n";
    vector < vector <int> > adjList(curcomponent+10);
    map < pair <int, int>, int > edgeExists; 
    for (int i=0; i<H; ++i)
    {
        for (int j=0; j<W; ++j)
        {
            if (component[i][j]==-1) continue;
            for (int k=i-2; k<=i+2; ++k)
            {
                for (int l=j-2; l<=j+2; ++l)
                {
                    if (k<0 || l<0) continue;
                    if (k>=H || l>=W) continue;
                    if (component[k][l]==-1 || component[k][l]==component[i][j]) continue;
                    if (edgeExists.find({component[i][j], component[k][l]})==edgeExists.end()) {
                        // cout << i << " " << j << " " << k << " " << l << " " << component[i][j] << " " << component[k][l] <<  endl;
                        adjList[component[i][j]].push_back(component[k][l]);
                        adjList[component[k][l]].push_back(component[i][j]);
                        edgeExists[{component[i][j], component[k][l]}] = edgeExists[{component[k][l], component[i][j]}] = 1;
                    }
                }
            }
        }
    }
    int source = component[start.first-1][start.second-1];
    int dest= component[end.first-1][end.second-1];
    // cout << source << " " << dest << endl;
    queue <int> Q;
    Q.push(source);
    vector <int> dist(curcomponent+1, -1);
    dist[source]=0;
    vector <bool> visited2(curcomponent+1, false);
    visited2[source]=true;
    while (!Q.empty())
    {
        int node=Q.front(); Q.pop();
        for (auto z: adjList[node])
        {
            if (!visited2[z])
            {
                visited2[z]=true;
                dist[z]=dist[node]+1;
                Q.push(z);
            }
        }
    }
    cout << dist[dest] << "\n";
    return 0;
}

Measured memory_bytes: 40612