using System;
using System.Collections.Generic;
using System.Linq;
namespace AIZU
{
struct V
{
public V(int ny, int nx) { x = nx; y = ny; }
public int x;
public int y;
public static V operator +(V a, V b) => new V(a.y+ b.y, a.x + b.x);
public static bool operator ==(V a, V b) => a.x == b.x && a.y == b.y;
public static bool operator !=(V a, V b) => a.x != b.x || a.y != b.y;
public override string ToString() => $"{x},{y}";
public override bool Equals(object X) { if (X == null || !(X is V)) return false; return (V)X == this; }
public override int GetHashCode() => base.GetHashCode();
}
class Program
{
#region Reserve
static int cin() { return cin(-1); }
static int cin(int D)
{
string s = Console.ReadLine();
if (string.IsNullOrEmpty(s))
return D;
return int.Parse(s);
}
static int[] cins(char spliter)
{
string s = Console.ReadLine();
if (string.IsNullOrEmpty(s))
return new int[] { };
string[] ss = s.Split(spliter);
int[] Res = new int[ss.Length];
int g;
for (int i = 0; i < ss.Length; i++) {
if (int.TryParse(ss[i], out g))
Res[i] = g;
}
return Res;
}
static int[] cins() { return cins(' '); }
static long[] lins(char spliter)
{
string s = Console.ReadLine();
if (string.IsNullOrEmpty(s))
return new long[] { };
string[] ss = s.Split(spliter);
long[] Res = new long[ss.Length];
long g;
for (int i = 0; i < ss.Length; i++) {
if (long.TryParse(ss[i], out g))
Res[i] = g;
}
return Res;
}
static long[] lins() { return lins(' '); }
static void print(object j) { Console.WriteLine(j.ToString()); }
static void print(string j) { Console.WriteLine(j); }
#endregion
static bool[,] Pass;
static bool BOP (V v){
return Pass[v.y,v.x];
}
static void Main(string[] args)
{
int[] I = cins();
int R = I[0], C = I[1];
Pass = new bool[R, C]; ;
I = cins();
int sy = I[0] - 1, sx = I[1] - 1;
I = cins();
int gy = I[0] - 1, gx = I[1] - 1;
string Road;
for (int iop = 0; iop < R; iop++) {
Road = Console.ReadLine();
for (int jop = 0; jop < C; jop++) {
Pass[iop, jop] = Road[jop] == '.';
}
}
print(Explore(new V(sy,sx),new V(gy,gx)));
Console.ReadLine();
}
static Queue<V> Frontier = new Queue<V>();
static V[]Adja = new V[]{ new V(1,0),new V(0,1),new V(-1,0),new V(0,-1) };
static int Explore(V v0, V goal)
{
HashSet<V> G = new HashSet<V>();
G.Clear();
Frontier.Enqueue(v0); G.Add(v0);
V v;
int level = 0;
int beta = 0;
while (Frontier.Count > 0) {
if (beta == 0) { level++; beta = Frontier.Count(); }
v = Frontier.Peek();
foreach (V d in Adja) {
if (!BOP(v+d) || G.Contains(v + d)) continue;
Frontier.Enqueue(v + d); G.Add(v + d);
if (v + d == goal) goto E;
}
Frontier.Dequeue();
beta--;
}
E:
return level;
}
}
}