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

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var input1 = Console.ReadLine().Split().Select(int.Parse).ToArray();
            var input2 = Console.ReadLine().Split().Select(int.Parse).ToArray();
            var input3 = Console.ReadLine().Split().Select(int.Parse).ToArray();
            var H = input1[0];
            var W = input1[1];
            var Ch = input2[0] - 1;
            var Cw = input2[1] - 1;
            var Dh = input3[0] - 1;
            var Dw = input3[1] - 1;
            var S = new int[H, W];
            for (int i = 0; i < H; i++)
            {
                var line = Console.ReadLine().ToCharArray();
                for (int j = 0; j < W; j++)
                {
                    S[i, j] = line[j] == '#' ? -1 : int.MaxValue;
                }
            }

            S[Ch, Cw] = 0;
            FillAll(S, (Ch, Cw), (Dh, Dw));

            var ans = S[Dh, Dw];
            Console.WriteLine(ans == int.MaxValue ? -1 : ans);
        }

        static void FillAll(int[,] S, (int, int) start, (int, int) goal)
        {
            var tArray = new[] { start };
            while (true)
            {
                var ret = FillAll(S, tArray, goal);
                if (!ret.Any()) return;
                tArray = ret;
            }
        }

        static (int, int)[] FillAll(int[,] S, (int, int)[] tArray, (int, int) goal)
        {
            var valueCells = FillWalkAll(S, tArray);
            if (valueCells.Contains(goal)) return new (int, int)[0];

            return FillWarpAll(S, valueCells);
        }

        static (int, int)[] FillWalkAll(int[,] S, (int, int)[] tArray)
        {
            var ret = tArray.SelectMany(t => FillWalk(S, t)).ToArray();
            if (!ret.Any()) return tArray.ToArray();

            return tArray.Concat(FillWalkAll(S, ret)).ToArray();
        }

        static (int, int)[] FillWalk(int[,] S, (int, int) t)
        {
            var value = S[t.Item1, t.Item2];
            return WalkArea(t).Where(x => Fill(S, x.Item1, x.Item2, value)).ToArray();
        }

        static (int, int)[] FillWarpAll(int[,] S, (int, int)[] tArray)
        {
            return tArray.SelectMany(t => FillWarp(S, t)).ToArray();
        }

        static (int, int)[] FillWarp(int[,] S, (int, int) t)
        {
            var value = S[t.Item1, t.Item2] + 1;
            return WarpArea(t).Where(x => Fill(S, x.Item1, x.Item2, value)).ToArray();
        }

        static (int, int)[] WalkArea((int, int) t)
        {
            return new[]
            {
                (t.Item1 - 1, t.Item2),
                (t.Item1 + 1, t.Item2),
                (t.Item1, t.Item2 - 1),
                (t.Item1, t.Item2 + 1)
            };
        }

        static (int, int)[] WarpArea((int, int) t)
        {
            var ret = new List<(int, int)>();
            for (int i = -2; i <= 2; i++)
            {
                for (int j = -2; j <= 2; j++)
                {
                    if (i == 0 && j == 0) continue;
                    ret.Add((t.Item1 + i, t.Item2 + j));
                }
            }

            return ret.ToArray();
        }

        static bool Fill(int[,] S, int i, int j, int value)
        {
            if (Judge(S, i, j))
            {
                S[i, j] = value;
                return true;
            }

            return false;
        }

        static bool Judge(int[,] S, int i, int j)
        {
            return 0 <= i && i < S.GetLength(0)
                && 0 <= j && j < S.GetLength(1)
                && S[i, j] == int.MaxValue;
        }
    }
}


Measured memory_bytes: 50784