#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;

#define endl            "\n"
#define forn(i,x1,n)     for(int i=x1; i<n; i++)
#define forit(it, m)    for(decltype(m)::iterator it = m.begin(); it!=m.end(); ++it)
#define ff              first
#define ss              second
#define int             long long
#define pb              push_back
#define mp              make_pair
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x1)      __builtin_popcountll(x1)
#define zrobits(x1)      __builtin_ctzll(x1)
#define mod             1000000007
#define inf             1e18
#define ps(x1,y)         fixed<<setprecision(y)<<x1
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x1)            int x1; cin>>x1; while(x1--)
mt19937                 rng(chrono::steady_clock::now().time_since_epoch().count());


void zeus()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
}

int h, w;
int ch, cw;
int dh, dw;
int l = 1;
char maze[1001][1001];
int islands[1001][1001];

vector<pair<int, int>> dir = {{1, 0}, {0, 1}, { -1, 0}, {0, -1}};

int visited[1001][1001];

bool isin(int i, int j) {
    return (i > 0 && j > 0 && i <= h && j <= w);
}

void bfs(int i, int j) {

    visited[i][j] = 1;
    queue<pair<int, int>> q;
    q.push({i, j});
    islands[i][j] = l;

    while (!q.empty()) {
        pii x = q.front();
        q.pop();
        forn(i, 0, 4) {
            pii y = {x.ff + dir[i].ff, x.ss + dir[i].ss};
            if (isin(y.ff, y.ss) && maze[y.ff][y.ss] == '.' && visited[y.ff][y.ss] == 0) {
                visited[y.ff][y.ss] = 1;
                q.push({y.ff, y.ss});
                islands[y.ff][y.ss] = l;
            }
        }
    }
}


int32_t main() {

    zeus();
    cin >> h >> w;

    cin >> ch >> cw;
    cin >> dh >> dw;

    forn(i, 1, h + 1) {
        forn(j, 1, w + 1) {
            cin >> maze[i][j];
        }
    }

    forn(i, 1, h + 1) {
        forn(j, 1, w + 1) {
            if (visited[i][j] == 0 && maze[i][j] == '.') {
                bfs(i, j);
                l++;
            }
        }
    }
    set<int> adj[l];
    forn(i, 1, h + 1) {
        forn(j, 1, w + 1) {
            // cout << islands[i][j] << " ";
            forn(i1, i - 2, i + 3) {
                forn(j1, j - 2, j + 3) {
                    if (isin(i1, j1) && islands[i][j] != islands[i1][j1] && islands[i][j] != 0 && islands[i1][j1] != 0) {
                        adj[islands[i][j]].insert(islands[i1][j1]);
                        adj[islands[i1][j1]].insert(islands[i][j]);
                    }
                }
            }
        }
        // cout << endl;
    }

    int x = islands[ch][cw];
    int y = islands[dh][dw];
    if (x == y) {
        cout << 0 << endl;
        return 0;
    }
    // cout << x << " " << y << endl;
    int dist[l];
    memset(dist, -1, sizeof dist);
    int visited2[l] = {0};

    queue<int> q;
    q.push(x);
    visited2[x] = 1;
    dist[x] = 0;
    // cout << x << endl;
    while (!q.empty()) {
        int z = q.front();
        q.pop();
        set<int> temp = adj[z];
        forit(it, temp) {
            if (!visited2[*it]) {
                visited2[*it] = 1;
                dist[*it] = 1 + dist[z];
                q.push(*it);
                if (*it == y) {
                    cout << dist[*it] << endl;
                    return 0;
                }
            }
        }
    }

    cout << -1 << endl;





}








Measured memory_bytes: 46404