using System;
using System.Collections.Generic;
using System.Linq;

public struct Point
{
    public int X;
    public int Y;

    public Point(Point p)
    {
        X = p.X;
        Y = p.Y;
    }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public static bool operator ==(Point a, Point b)
    {
        return (a.X == b.X && a.Y == b.Y);
    }

    public static bool operator !=(Point a, Point b)
    {
        return !(a == b);
    }

    //objと自分自身が等価のときはtrueを返す
    public override bool Equals(object obj)
    {
        if (!(obj is Point))
        {
            return false;
        }

        Point p = (Point)obj;
        return (X == p.X && Y == p.Y);
    }

    //Equalsがtrueを返すときに同じ値を返す
    public override int GetHashCode()
    {
        return (X << 16) ^ Y;
    }

    public Point Clone()
    {
        return new Point(X, Y);
    }

    public void Reverse()
    {
        X = -X;
        Y = -Y;
    }

    public static Point operator +(Point a, Point b)
    {
        return new Point(a.X + b.X, a.Y + b.Y);
    }

    public static Point operator -(Point a, Point b)
    {
        return new Point(a.X - b.X, a.Y - b.Y);
    }

    public static Point operator *(Point a, int i)
    {
        return new Point(a.X * i, a.Y * i);
    }

    public static Point operator /(Point a, int i)
    {
        return new Point(a.X / i, a.Y / i);
    }
    public static Point operator +(Point a)
    {
        return new Point(+a.X, +a.Y);
    }

    public static Point operator -(Point a)
    {
        return new Point(-a.X, -a.Y);
    }

    public override string ToString()
    {
        return string.Format("({0},{1})", X, Y);
    }

    IEnumerable<Point> _GetNeighbor()
    {
        yield return new Point(X + 1, Y + 0);
        yield return new Point(X + 0, Y + 1);
        yield return new Point(X - 1, Y + 0);
        yield return new Point(X + 0, Y - 1);
    }

    public static Point Max;

    public bool InRange(Point max)
    {
        return 0 <= X && X < max.X && 0 <= Y && Y < max.Y;
    }

    public IEnumerable<Point> GetNeighbor()
    {
        return _GetNeighbor().Where(p => p.InRange(Max));
    }

    public IEnumerable<Point> Get5Neighbor()
    {
        for (int dy = -2; dy <= 2; dy++)
        {
            for (int dx = -2; dx <= 2; dx++)
            {
                var p = new Point(X + dx, Y + dy);
                if (p.InRange(Max))
                {
                    yield return p;
                }
            }
        }
    }
}

public static class Solution
{
    static HashSet<Point> GetChain(string[] field, Point start)
    {
        var visited = new HashSet<Point>();
        visited.Add(start);
        var queue = new Queue<Point>();
        queue.Enqueue(start);
        while (queue.Count > 0)
        {
            var cur = queue.Dequeue();
            foreach (var nei in cur.GetNeighbor().Where(p => field[p.Y][p.X] == '.'))
            {
                if (!visited.Contains(nei))
                {
                    visited.Add(nei);
                    queue.Enqueue(nei);
                }
            }
        }

        return visited;
    }

    public static void Main()
    {
        var vals = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        var H = vals[0];
        var W = vals[1];
        Point.Max = new Point(W, H);
        vals = Console.ReadLine().Split(' ').Select(x => int.Parse(x) - 1).ToArray();
        var start = new Point(vals[1], vals[0]);
        vals = Console.ReadLine().Split(' ').Select(x => int.Parse(x) - 1).ToArray();
        var goal = new Point(vals[1], vals[0]);
        var field = new string[H];
        for (int y = 0; y < H; y++)
        {
            field[y] = Console.ReadLine();
        }
        var id = 0;
        var p2id = new Dictionary<Point, int>();
        var id2p = new List<HashSet<Point>>();
        for (int y = 0; y < H; y++)
        {
            for (int x = 0; x < W; x++)
            {
                var p = new Point(x, y);
                if (field[p.Y][p.X] != '.' || p2id.ContainsKey(p))
                {
                    continue;
                }
                var chain = GetChain(field, p);
                foreach (var pp in chain)
                {
                    p2id[pp] = id;
                }
                id2p.Add(chain);
                id++;
            }
        }

        var currents = new List<int> { p2id[start] };
        var warp = 0;
        var visited = new HashSet<int>(currents);
        while (currents.Count > 0)
        {
            if (currents.Any(cur => id2p[cur].Contains(goal)))
            {
                Console.WriteLine(warp);
                return;
            }

            var nexts = new List<int>();
            foreach (var p in currents.SelectMany(cur => id2p[cur]))
            {
                foreach (var nei in p.Get5Neighbor().Where(pp => field[pp.Y][pp.X] == '.'))
                {
                    var neiid = p2id[nei];
                    if (!visited.Contains(neiid))
                    {
                        visited.Add(neiid);
                        nexts.Add(neiid);
                    }
                }
            }
            currents = nexts;
            warp++;
        }

        Console.WriteLine(-1);
    }
}

Measured memory_bytes: 103216