#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <deque>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

typedef long long ll;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
constexpr double PI = 3.141592653589793;
constexpr int INF = 1e9 + 10;
constexpr ll INFL = 1e18 + 10;

template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}

using namespace std;
//    cout << setprecision(20) << ans << "\n";


int main(){
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int dx[] = { 1, 0, -1, 0 };
    int dy[] = {0, 1, 0, -1};
    int nwarpx[] = { 1, -1, 1, -1, 2, 2, 2, 2, 2, 1, 1, 0, 0,  -1, -1, -2, -2, -2, -2, -2};
    int nwarpy[] = { 1, -1, -1, 1, 0, 1, 2, -1, -2, 2, -2, 2, -2, 2, -2, 2, 1, 0, -1, -2};
    // int n, x, t;
    // cin >> n >> x >> t;
    // cout << (n / x + 1) * t << "\n";

    int h, w;
    cin >> h >> w;
    int ch, cw, th, tw;
    cin >> ch >> cw >> th >> tw;
    ch--;
    cw--;
    th--;
    tw--;
    vector<vector<char>> field(h, vector<char>(w));
    vector<vector<int>> dist(h, vector<int>(w, INF));
    vector<vector<int>> visited(h, vector<int>(w, 0));
    for (int i = 0; i < h; i++)
    {
        for (int j = 0; j < w; j++)
        {
            cin >> field[i][j];
            if (field[i][j] == '#'){
                visited[i][j] = 1;
            }
        }
    }
    deque<pair<int, int>> que;
    que.push_front(make_pair(ch, cw));
    int curdist = 0;
    dist[ch][cw] = 0;
    while (!que.empty())
    {
        auto cur = que.front();
        que.pop_front();
        for (int i = 0; i < 4; i++)
        {
            int ny = cur.first + dy[i];
            int nx = cur.second + dx[i];
            if (ny < 0 || nx < 0 || ny >= h || nx >= w){
                continue;
            } 
            if (field[ny][nx] == '#' || visited[ny][nx]){
                continue;
            }
            if (dist[ny][nx] > dist[cur.first][cur.second])
            {
                que.push_front({ny,nx});
                dist[ny][nx] = dist[cur.first][cur.second];
            }
        }
        for (int i = -2; i <= 2; i++)
        {
            for (int j = -2; j <= 2; j++)
            {
                int ny = cur.first + i;
                int nx = cur.second + j;
                if (ny < 0 || nx < 0 || ny >= h || nx >= w){
                    continue;
                } 
                if (field[ny][nx] == '#' || visited[ny][nx]){
                    continue;
                }
                if (dist[ny][nx] > dist[cur.first][cur.second] + 1){
                    que.push_back({ny, nx});
                    dist[ny][nx] = dist[cur.first][cur.second] + 1;
                }
            }
        }
    }
    if (dist[th][tw] == INF){
        cout << -1 << "\n";
        return 0;
    }
    cout << dist[th][tw] << "\n";

    return 0;
}


Measured memory_bytes: 12580