// Coder : Hellolin
// Time : 2023-02-06 12:32:38
// Problem : [ABC176D] Wizard in Maze
// Contest : Luogu
// URL : https://www.luogu.com.cn/problem/AT_abc176_d
// Time Limit : 2000 ms
// Memory Limit : 1 GiB
#include <iostream>
#include <utility> // pair 大法好
#include <deque>
#include <cstring>
using namespace std;
#define pi pair<int, int>
#define fi first
#define se second
#define rep(x, y, z) for (int x = y; x <= z; x++)
const int MAX = 1e3 + 114;
deque<pi> a;
int dx[5] = {0, 1, -1, 0, 0};
int dy[5] = {0, 0, 0, 1, -1};
int path[MAX][MAX];
int h, w, ans;
// 开始位置 结束位置 当前位置 下一个移动位置
pi str, fin, now, mv;
char tmp;
bool img[MAX][MAX];
void init()
{
ans = -1;
memset(path, -1, sizeof(path));
// 记得起始位置 path 设 0
path[str.fi][str.fi] = 0;
a.clear();
// 在前面压一个开始位置
a.push_front(str);
}
void bfs()
{
while (a.size()) // while (!a.empty())
{
now = a.front();
a.pop_front();
if (now == fin) // 到终点了
{
ans = path[now.fi][now.se];
return;
}
// 上下左右四个方向
rep(i, 1, 4)
{
mv = now;
mv.fi += dx[i];
mv.se += dy[i];
if (mv.fi < 1 || mv.fi > h || mv.se < 1 || mv.se > w) // 越界检查
continue;
if (!img[mv.fi][mv.se])
{
// 当前这条路还没走过,或者当前这条路使用过魔法次数较少
if (path[mv.fi][mv.se] == -1 || path[mv.fi][mv.se] > path[now.fi][now.se])
{
// 普通移动,放到队首
a.push_front(mv);
// 普通移动不需要 +1
path[mv.fi][mv.se] = path[now.fi][now.se];
}
}
}
// 以当前方格为中心的 5x5
rep(x, now.fi - 2, now.fi + 2)
{
rep(y, now.se - 2, now.se + 2)
{
if (x < 1 || x > h || y < 1 || y > w) // 越界检查
continue;
if (!img[x][y])
{
// 当前这条路还没走过
if (path[x][y] == -1)
{
// 魔法移动,放到队尾
a.push_back({x, y});
// 魔法移动记得 +1
path[x][y] = path[now.fi][now.se] + 1;
}
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> h >> w;
cin >> str.fi >> str.se;
cin >> fin.fi >> fin.se;
rep(i, 1, h)
{
rep(j, 1, w)
{
cin >> tmp;
img[i][j] = (tmp == '#'); // 记 墙=1 路=0
}
}
init();
bfs();
cout << ans << endl;
return 0;
}