#include <bits/stdc++.h>
#include <iostream>
#include <ctime>
using namespace std;
#define _LL long long
#define rep(i, n) for (_LL i = 0; i < (_LL)(n); i++)
#define vecrep(itr, v) for (auto itr = (v).begin(); itr != (v).end(); itr++)

template <class T> class MultiArray2
{
    public:
        T* _a;
        int _w;
        int _h;
        MultiArray2(int w, int h, bool clr = false)
        {
            _w = w; _h = h;
            _a = new T[_w * _h];
            if(clr) memzero();
        }

        void memzero()
        {
            memset(_a, 0, _w * _h * sizeof(T));
        }

        ~MultiArray2()
        {
            delete _a;
        }

        T* operator[](int i)
        {
            return _a + (i * _h);
        }

        void print()
        {
            for( int j = 0; j < _h; j++ )
            {
                for( int i = 0; i < _w; i++ )
                {
                    cout << (*this)[i][j] << " ";
                }
                cout << endl;
            }
        }

        bool inside(int i, int j)
        {
            return (i >= 0 && i < _w && j >= 0 && j < _h );
        }

};

MultiArray2<bool> * _maze;
MultiArray2<int> * _dist;
priority_queue<pair<int, pair<int, int>>> * _q;
int dh;
int dw;

inline void qpush(int i, int j, int d)
{
    if( !_maze->inside(i, j) ) return;
    if( !(*_maze)[i][j] ) return;
    if( (*_dist)[i][j] != 0 ) return;
    _q->push(make_pair(-d, make_pair(i, j)));
}

bool nsearch(int i, int j, int d )
{
    if( i == dh && j == dw ) return true;
    if( !_maze->inside(i, j) ) return false;
    if( !(*_maze)[i][j] ) return false;
    if( (*_dist)[i][j] != 0 ) return false;
    (*_dist)[i][j] = d;

    _q->push(make_pair(- d - 1, make_pair(i, j)));
    qpush(i + 1, j, d);
    qpush(i, j + 1, d);
    qpush(i - 1, j, d);
    qpush(i, j - 1, d);
    return false;
}

int main()
{
#if 1    
    int h, w; cin >> h >> w;
    int ch, cw; cin >> ch >> cw; ch--; cw--;
    cin >> dh >> dw; dh--; dw--;    
    MultiArray2<bool> maze(h, w);
    rep(i, h)
    {
        string s; cin >> s;
        rep(j, w) maze[i][j] = (s[j] == '.');
    }
#else
    int h, w; h = 1000; w = 1000;
    int ch, cw; ch = 0; cw = 0;
    dh = 998; dw = 999;    
    MultiArray2<bool> maze(h, w);
    rep(i, h)
    {
        rep(j, w) maze[i][j] = (i % 2 == 0 || ( (i / 2) % 2 == 0 && j == 0 ) || ( (i / 2) % 2 == 1 && j == w - 1 ));
    }
#endif
    MultiArray2<int> dist(h, w, true);
    priority_queue<pair<int, pair<int, int>>> q;

    _maze = &maze;
    _dist = &dist;
    _q = &q;

    q.push(make_pair(-1, make_pair(ch, cw)));
    while( !q.empty() )
    {
        auto next = q.top();
        q.pop();
        int i = next.second.first;
        int j = next.second.second;
//        cout << i << "," << j << endl;
        if( i < 0 || i >= h || j < 0 || j >= w) continue;
        if( (-next.first) % 2 == 1 )
        {
            if( dist[i][j] != 0 ) continue;
            if( nsearch(i, j, -next.first) )
            {
                cout << (-next.first) / 2;
                return 0;
            }
        }
        else
        {
            rep(k, 5)
                rep(l, 5)
                {
                    qpush(i - 2 + k, j - 2 + l, -next.first + 1);
                }
        }
    }

    cout << -1;
}

Measured memory_bytes: 8416