//C++
//#pragma comment(linker, "/STACK:102400000,102400000")
//G++
//#define OPENSTACK
#define ONLINE_JUDGE
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cctype>
using namespace std;
typedef long long LL;
typedef pair<LL, pair<int, int>> PIII;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int MOD = 998244353;
const int N = 1e3 + 10, M = N;//刻意开大会消耗时间.

char ca[N][N];
bool st[N][N];
//int dist[N][N];
int n, m;
PII start, endPoint;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int ddx[] = {-1, 1, 1, -1,  -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2};
int ddy[] = {1, 1, -1, -1,  0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1};
// 对角线: 直接加到ddx的后面
// int dddx[] = {-1, 1, 1, -1}, dddy[] = {1, 1, -1, -1};

// 双端队列?
long long bfs(int x, int y){
    //memset(dist, 0x3f, sizeof dist);
    memset(st, false, sizeof st);

    deque<PIII> q;
    q.push_front({0, {x, y}});
    //dist[x][y] = 0;

    while(q.size()){
        auto t = q.front();
        q.pop_front();
        
        long long dist = t.first;
        int x = t.second.first, y = t.second.second;
        if(x == endPoint.first && y == endPoint.second) return dist;

        if(st[x][y]) continue; 
        st[x][y] = true;
        
        int cnt = 0;
        // 对于A
        for(int i = 0; i < 4; i ++){
            int a = x + dx[i], b = y + dy[i];
            if(a < 1 || a > n || b < 1 || b > m || st[a][b] || ca[a][b] == '#') {
                cnt ++; continue;}
            q.push_front({dist, {a, b}}); 
        }

        // 对于B, 当A没有办法的时候才用B
        //if(cnt == 4){
  //          cout << "x: " << x << "y: " << y << endl;
        for(int i = 0; i < 20; i ++){
            int a = x + ddx[i], b = y + ddy[i];
            if(a < 1 || a > n || b < 1 || b > m || st[a][b] || ca[a][b] == '#') continue;
            // 如果(a, b)之前已经被更新过怎么办.
            // 因为会影响dist[a][b], 直接放在deque比较好.
            //dist[a][b] = min(dist[a][b], dist[x][y] + 1);    
            q.push_back({dist + 1, {a, b}});
        }
        //}
    }
    return -1;
}

int main()
{
    #ifdef OPENSTACK
    int size = 64 << 20; // 64MB
    char *p = (char*)malloc(size) + size;
    #if (defined _WIN64) or (defined __unix)
        __asm__("movq %0, %%rsp\n" :: "r"(p));
    #else
        __asm__("movl %0, %%esp\n" :: "r"(p));
    #endif
    #endif
    #ifndef ONLINE_JUDGE
        freopen("../put/a.input","r",stdin);
        freopen("../put/a.output","w",stdout);
    #endif
    clock_t c1 = clock();
    //coding here......

    cin >> n >> m;
    cin >> start.first >> start.second;
    cin >> endPoint.first >> endPoint.second;

    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            cin >> ca[i][j];

    // 如果判断需要跳的步数:
    // 假设A的代价是0, B的代价是1.
    // 求start到end的最小代价就可以了.
    int res = bfs(start.first, start.second); 

    cout << res << endl;

    //finish here......
    #ifndef ONLINE_JUDGE
        std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
    #endif
    #ifdef OPENSTACK
        exit(0);
    #else
        return 0;
    #endif
}

Measured memory_bytes: 6220