#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <math.h>
#include <cstdlib>
#include <queue>
#include <iterator>
#include <limits>
#include <string>
#include <sstream>
#include <iomanip>
#include <bitset>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <stack>
#include <memory>
#include <deque>
#include <string_view>
#include <random>
#include <chrono>
#include <cstring>

using namespace std;

static int my_speed_up = []() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return 0; }();
using ll = long long; using ull = unsigned long long;
template<class T> using v = vector<T>;
template<class T> using vv = vector<vector<T>>;
template<class T> using vvv = vector<vector<vector<T>>>;
template<class T> using vvvv = vector<vector<vector<vector<T>>>>;
#define for_b(i, b) for (int i = 0; i < (b); ++i)
#define for_ab(i, a, b) for (int i = a; i < (b); ++i)
#define what_is(x) cout << #x << " = " << x << endl;
#define what_are(x,y) cout << #x << " = " << x << ", " << #y << " = " << y << endl;
#define pad(x) for_b(i, x) cout << "  ";
#define show_1d(___x) cout << #___x << " = "; for (auto& ___num : ___x) cout << ___num << ", "; cout << endl;
#define show_2d(___x) cout << #___x << endl; for (auto& ___row : ___x) { for (auto ___num : ___row) cout << ___num << ", "; cout << endl; }
#define show_3d(___x) cout << #___x << endl; for (auto& ___row : ___x) { for (auto& ___row2 : ___row) { for (auto ___num : ___row2) cout << ___num << ", "; cout << endl; }cout << endl; }

vv<int> d4 = {{1,0},{-1,0},{0,1},{0,-1}};
vv<int> d8 = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
bool is_valid_pos(const vv<int>& tb, int x, int y) {
    return x >= 0 && x < tb.size() && y >= 0 && y < tb[0].size();
}


int main()
{
    int H, W;
    cin >> H >> W;
    
    int cx, cy;
    cin >> cx >> cy;
    --cx; --cy;
    
    int dx, dy;
    cin >> dx >> dy;
    --dx; --dy;
    
    vv<char> tb (H, v<char>(W));
    for_b(i,H)
    for_b(j,W)
    cin >> tb[i][j];
    
    vv<int> step(H, v<int>(W, H*W+1));
    
    vv<int> q[2];
    int cur_q = 0;
    q[0].push_back({cx, cy});
    
    int cur_magic = 0;
    
    unordered_set<int> next_magic_level;
    
    while (true)
    {
        while (!q[cur_q].empty())
        {
            int next_q = cur_q ^ 1;
            
            for (auto& cur_node : q[cur_q])
            {
                if (auto it = next_magic_level.find(cur_node[0] * 10000 + cur_node[1]); it != next_magic_level.end())
                    next_magic_level.erase(it);
                
                if (step[cur_node[0]][cur_node[1]] > cur_magic)
                {
                    step[cur_node[0]][cur_node[1]] = cur_magic;
                    for (auto& d : d4)
                    {
                        int nx = cur_node[0] + d[0];
                        int ny = cur_node[1] + d[1];
                        if (is_valid_pos(step, nx, ny) && tb[nx][ny] != '#' && step[nx][ny] > cur_magic)
                            q[next_q].push_back({nx, ny});
                    }
                    for (int i = -2 ; i <= 2 ; ++i)
                    {
                        for (int j = -2 ; j <= 2; ++j)
                        {
                            if (i != 0 || j != 0)
                            {
                                int nx = cur_node[0] + i;
                                int ny = cur_node[1] + j;
                                if (is_valid_pos(step, nx, ny) && tb[nx][ny] != '#' && step[nx][ny] > cur_magic + 1)
                                {
                                    next_magic_level.insert(nx * 10000 + ny);
                                }
                            }
                        }
                    }
                }
            }
            q[cur_q].clear();
            cur_q = next_q;
        }
        if (step[dx][dy] < H*W+1) break;
        ++cur_magic;
        if (next_magic_level.empty()) break;
        for (auto item : next_magic_level)
            q[cur_q].push_back({item / 10000, item % 10000});
        next_magic_level.clear();
    }
    
    cout << (step[dx][dy] < H*W+1 ? step[dx][dy] : -1) << endl;
    
    return 0;
}


Measured memory_bytes: 8916