#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
const int MAXN = 1005;
const int INF = 1e9;
char g[MAXN][MAXN];
int dist[MAXN][MAXN];
int dr[4] = {-1, 1, 0, 0}, dc[4] = {0, 0, -1, 1};
static pair<int,int> cur[MAXN * MAXN], nxt[MAXN * MAXN];
int cur_h, cur_t, nxt_h, nxt_t;
int main(){
int h, w, a, b, ct, dt;
scanf("%d%d", &h, &w);
for(int i = 1; i <= h; i++) scanf("%s", g[i] + 1);
scanf("%d%d%d%d", &a, &b, &ct, &dt);
for(int i = 1; i <= h; i++)
for(int j = 1; j <= w; j++) dist[i][j] = INF;
dist[a][b] = 0;
cur_h = 0; cur_t = 0; nxt_h = 0; nxt_t = 0;
cur[cur_t++] = {a, b};
// 分层 BFS: cur = dist=k 的所有点
while(cur_h < cur_t){
while(cur_h < cur_t){
auto [r, c] = cur[cur_h++];
int d = dist[r][c];
// 移动到 . 邻居 (cost 0):保持在当前 dist=k 层
for(int k = 0; k < 4; k++){
int nr = r + dr[k], nc = c + dc[k];
if(nr < 1 || nr > h || nc < 1 || nc > w) continue;
if(g[nr][nc] != '.') continue;
if(dist[nr][nc] > d){
dist[nr][nc] = d;
cur[cur_t++] = {nr, nc};
}
}
}
// 踢:所有当前 dist=k 的点踢出 dist=k+1 的候选
// 但此时 cur 已经耗尽(移动完成)→ 需重新遍历地图找 dist=k 的点? O(H*W)
// 改: 踢时记录"踢起点", 移动时优先踢
// 实际上: 用一个标志位, cur 中点先尝试踢再尝试移动
break; // 不跳出,继续下面重写
}
// 重写:使用单一 deque 但严格 0-1 BFS
// 0-1 BFS 重复入队可能多,改为 Dijkstra + 邻接表
// 或者: 用数组模拟双端队列 + 每个点最多入队 2 次
// 简化: 我直接用 std::deque,但只入队踢动作的候选,移动操作不重新入队
// 重写真正简洁版
for(int i = 1; i <= h; i++)
for(int j = 1; j <= w; j++) dist[i][j] = INF;
dist[a][b] = 0;
deque<pair<int,int>> dq;
dq.push_front({a, b});
while(!dq.empty()){
auto [r, c] = dq.front(); dq.pop_front();
int d = dist[r][c];
// 移动 (cost 0): . 邻居
for(int k = 0; k < 4; k++){
int nr = r + dr[k], nc = c + dc[k];
if(nr < 1 || nr > h || nc < 1 || nc > w) continue;
if(g[nr][nc] != '.') continue;
if(dist[nr][nc] > d){
dist[nr][nc] = d;
dq.push_front({nr, nc});
}
}
// 踢 (cost 1): p1, p2
for(int k = 0; k < 4; k++){
int r1 = r + dr[k], c1 = c + dc[k];
if(r1 < 1 || r1 > h || c1 < 1 || c1 > w) continue;
if(dist[r1][c1] > d + 1){
dist[r1][c1] = d + 1;
dq.push_back({r1, c1});
}
int r2 = r1 + dr[k], c2 = c1 + dc[k];
if(r2 < 1 || r2 > h || c2 < 1 || c2 > w) continue;
if(dist[r2][c2] > d + 1){
dist[r2][c2] = d + 1;
dq.push_back({r2, c2});
}
}
}
printf("%d\n", dist[ct][dt] == INF ? -1 : dist[ct][dt]);
return 0;
}