import std;
import core.bitop;

// dfmt off
ulong MAX = 100_100, MOD = 1_000_000_007, INF = 1_000_000_000_000;
alias sread = () => readln.chomp();
alias lread(T = long) = () => readln.chomp.to!(T);
alias aryread(T = long) = () => readln.split.to!(T[]);
void aryWrite(T = long)(T[] ary){ ary.map!(x => x.text()).join(' ').writeln(); }
alias Pair = Tuple!(long, "H", long, "W", long, "cost");
alias PQueue(T, alias less = "a>b") = BinaryHeap!(Array!T, less);
// dfmt on

void main()
{
    long h, w;
    scan(h, w);
    long cH, cW;
    scan(cH, cW);
    long dH, dW;
    scan(dH, dW);

    auto s = new string[](h);
    s.each!((ref x) => x = sread());
    auto cost = new long[][](h, w);
    cost.each!((ref x) => x[] = INF);

    void bfs01()
    {
        auto deq = DList!(Pair)(Pair(cH - 1, cW - 1, 0));
        auto determined = new bool[][](h, w);
        auto added = new bool[][](h, w);
        determined[cH - 1][cW - 1] = true;
        while (!deq.empty())
        {
            // deq.array.writeln();
            auto f = deq.front();
            deq.removeFront();
            determined[f.H][f.W] = true;
            if (f.cost < cost[f.H][f.W])
                cost[f.H][f.W] = f.cost;

            if (f.H - 1 >= 0 && (s[f.H - 1][f.W] == '.') && (!determined[f.H - 1][f.W]))
            {
                deq.insertFront(Pair(f.H - 1, f.W, f.cost));
                determined[f.H - 1][f.W] = true;
                added[f.H - 1][f.W] = true;
            }
            if (f.H + 1 < h && (s[f.H + 1][f.W] == '.') && (!determined[f.H + 1][f.W]))
            {
                deq.insertFront(Pair(f.H + 1, f.W, f.cost));
                determined[f.H + 1][f.W] = true;
                added[f.H + 1][f.W] = true;
            }
            if (f.W - 1 >= 0 && (s[f.H][f.W - 1] == '.') && (!determined[f.H][f.W - 1]))
            {
                deq.insertFront(Pair(f.H, f.W - 1, f.cost));
                determined[f.H][f.W - 1] = true;
                added[f.H][f.W - 1] = true;
            }
            if (f.W + 1 < w && (s[f.H][f.W + 1] == '.') && (!determined[f.H][f.W + 1]))
            {
                deq.insertFront(Pair(f.H, f.W + 1, f.cost));
                determined[f.H][f.W + 1] = true;
                added[f.H][f.W + 1] = true;
            }

            auto loops = [-2, -1, 0, 1, 2];
            foreach (HDiff; loops)
            {
                foreach (WDiff; loops)
                {
                    if ((f.H + HDiff < h && f.H + HDiff >= 0)
                            && (f.W + WDiff < w && f.W + WDiff >= 0)
                            && ((s[f.H + HDiff][f.W + WDiff] == '.'))
                            && (!determined[f.H + HDiff][f.W + WDiff])
                            && (!added[f.H + HDiff][f.W + WDiff]))
                    {
                        deq.insertBack(Pair(f.H + HDiff, f.W + WDiff, f.cost + 1));
                        added[f.H + HDiff][f.W + WDiff] = true;
                    }
                }
            }
        }
    }

    bfs01();
    // cost.each!(x => x.aryWrite());
    writeln(cost[dH - 1][dW - 1] == INF ? -1 : cost[dH - 1][dW - 1]);
}

void scan(TList...)(ref TList Args)
{
    auto line = readln.split();
    foreach (i, T; TList)
    {
        T val = line[i].to!(T);
        Args[i] = val;
    }
}


Measured memory_bytes: 23280