using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program
{
    const string Yes = "Yes";
    const string No = "No";
    const char White = '.';
    const char Black = '#';
    const long Mod = 1000000007;

    static void Main(string[] args) {
        checked {
#if DEBUG
            MyDebugger.Test(process, "../TextFile1.txt");
            //TestCaseMaker.MakeTestCase1("../TextFile2.txt");
            //MyDebugger.Test(process, "../TextFile2.txt");
#else
            object ret = process(new StreamReader(Console.OpenStandardInput()));
            Console.WriteLine(ret);
#endif
        }
    }

    static int h;
    static int w;
    static int ch;
    static int cw;
    static int dh;
    static int dw;
    static char[][] ss;
    static int[][] box;

    static object process(TextReader input) {
        var spl = input.ReadLine().Split(' ');
        h = int.Parse(spl[0]);
        w = int.Parse(spl[1]);

        spl = input.ReadLine().Split(' ');
        ch = int.Parse(spl[0]) -1;
        cw = int.Parse(spl[1]) -1;
        spl = input.ReadLine().Split(' ');
        dh = int.Parse(spl[0]) -1;
        dw = int.Parse(spl[1]) -1;

        ss = new char[h][];
        for (int i=0; i<h; i++) {
            ss[i] = input.ReadLine().ToCharArray();
        }

        box = new int[h][];
        for(int i=0; i<h; i++) {
            box[i] = new int[w];
            for(int j=0; j<w; j++) {
                box[i][j] = int.MaxValue;
            }
        }

        Search0();

        int ret = box[ch][cw];
        return ret == int.MaxValue ? -1 : ret;
    }

    static bool CanMove(int ph, int pw, int sco) {
        return 0 <= ph && ph < h && 0 <= pw && pw < w
            && ss[ph][pw] == White && sco < box[ph][pw];
    }

    //static int Search1(int ph, int pw) {

    //    //探索終了判定
    //    if (ph == ch && pw == cw) {
    //        return -1;
    //    }

    //    //次の再帰（徒歩）
    //    int sco = box[ph][pw];
    //    int ii = 0; int jj = 0;

    //    ii = -1; jj = 0;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 1; jj = 0;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 0; jj = -1;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 0; jj = 1;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }

    //    //次の再帰（ワープ）
    //    for (int i = -2; i <= 2; i++) {
    //        for (int j = -2; j <= 2; j++) {
    //            if (i == 0 && j == 0) continue;
    //            if (i == 1 && j == 0) continue;
    //            if (i == -1 && j == 0) continue;
    //            if (i == 0 && j == -1) continue;
    //            if (i == 0 && j == 1) continue;

    //            if (CanMove(ph + i, pw + j, sco)) {
    //                box[ph + i][pw + j] = sco;
    //                Search1(ph + i, pw + j);
    //            }
    //        }
    //    }

    //    return -1;
    //}

    //static int Search2(int ph, int pw) {

    //    //探索終了判定
    //    if (ph == ch && pw == cw) {
    //        return -1;
    //    }

    //    //次の再帰（徒歩）
    //    int sco = box[ph][pw];
    //    int ii = 0; int jj = 0;

    //    ii = -1; jj = 0;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 1; jj = 0;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 0; jj = -1;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    ii = 0; jj = 1;
    //    if (CanMove(ph + ii, pw + jj, sco)) {
    //        box[ph + ii][pw + jj] = sco;
    //        Search2(ph + ii, pw + jj);
    //    }
    //    return -1;
    //}

    static int Search0() {
        var q = new Queue<Point>();
        var q2 = new Queue<Point>();

        //最初の要素追加
        q.Enqueue(new Point(dh, dw));
        box[dh][dw] = 0;

        while (q.Any()) {
            var x = q.Dequeue();

            //探索終了判定
            if (x.ph == ch && x.pw == cw) {
                continue;
            }

            //次のキューイング

            int sco = box[x.ph][x.pw];

            //徒歩でいける範囲探索
            List<Point> ps = new List<Point>();
            ps.Add(x);

            q2.Enqueue(x);
            while (q2.Any()) {
                var x2 = q2.Dequeue();

                //探索終了判定
                if (x2.ph == ch && x2.pw == cw) {
                    continue;
                }
                int ii = 0; int jj = 0;

                ii = -1; jj = 0;
                if (CanMove(x2.ph + ii, x2.pw + jj, sco)) {
                    box[x2.ph + ii][x2.pw + jj] = sco;
                    var p = new Point(x2.ph + ii, x2.pw + jj);
                    q2.Enqueue(p);
                    ps.Add(p);
                }
                ii = 1; jj = 0;
                if (CanMove(x2.ph + ii, x2.pw + jj, sco)) {
                    box[x2.ph + ii][x2.pw + jj] = sco;
                    var p = new Point(x2.ph + ii, x2.pw + jj);
                    q2.Enqueue(p);
                    ps.Add(p);
                }
                ii = 0; jj = -1;
                if (CanMove(x2.ph + ii, x2.pw + jj, sco)) {
                    box[x2.ph + ii][x2.pw + jj] = sco;
                    var p = new Point(x2.ph + ii, x2.pw + jj);
                    q2.Enqueue(p);
                    ps.Add(p);
                }
                ii = 0; jj = 1;
                if (CanMove(x2.ph + ii, x2.pw + jj, sco)) {
                    box[x2.ph + ii][x2.pw + jj] = sco;
                    var p = new Point(x2.ph + ii, x2.pw + jj);
                    q2.Enqueue(p);
                    ps.Add(p);
                }
            }

            //ワープ
            foreach(var x3 in ps) {
                for (int i = -2; i <= 2; i++) {
                    for (int j = -2; j <= 2; j++) {
                        if (CanMove(x3.ph + i, x3.pw + j, sco + 1)) {
                            box[x3.ph + i][x3.pw + j] = sco + 1;
                            q.Enqueue(new Point(x3.ph + i, x3.pw + j));
                        }
                    }
                }
            }
        }

        //探索全域終了
        return -1;
    }

    class Point
    {
        public int ph;
        public int pw;
        public Point(int ph, int pw) {
            this.ph = ph;
            this.pw = pw;
        }
    }

    static long[] ToIntArray(string strs, int n) {
        var ret = new long[n];
        var spl = strs.Split(' ');
        for (int i = 0; i < n; i++)
            ret[i] = long.Parse(spl[i]);
        return ret;
    }
}


Measured memory_bytes: 47868