/* Aditya0412 */
#include <bits/stdc++.h>
using namespace std; 
typedef long long int ll;
#define pb push_back 
#define ve vector
#define vii vector < int >
#define vll vector < ll > 
#define pii pair < int , int >
#define pll pair < ll , ll >
#define vpl vector < pll >
#define fi first
#define all(a)      (a).begin(),(a).end()
#define si(x)       (int)((x).size())
#define debug(x)    cout<<#x<<" is "<<(x)<<endl;cout.flush();  
#define se second 
#define endl        '\n'
#define f(i,a,b)    for(int i=a;i<b;i++)
#define mem(a,x)          memset(a,x,sizeof(a))

// === Debug macro starts here ===

int recur_depth = 0;
#ifdef DEBUG
#define dbg(x) {++recur_depth; auto x_=x; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<__LINE__<<"\t"<<#x<<" = "<<x_<<"\e[39m"<<endl;}
#else
#define dbg(x)
#endif
template<typename Ostream, typename Cont>
typename enable_if<is_same<Ostream,ostream>::value, Ostream&>::type operator<<(Ostream& os,  const Cont& v){
    os<<"["; 
    for(auto& x:v){os<<x<<", ";}
    return os<<"]";
}
template<typename Ostream, typename ...Ts>
Ostream& operator<<(Ostream& os,  const pair<Ts...>& p){
    return os<<"{"<<p.first<<", "<<p.second<<"}";
}

// === Debug macro ends here ===


// const ll mod=998244353;
const ll mod = 1000000000+7;
const ll N=1000000+6;
#define M_PI           3.14159265358979323846
void inp(ll *arr,ll n)
{
  for(int i=0;i<n;i++)
    cin>>arr[i];
}
void inp_mat(ll *arr,ll n,ll m)
{
    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++)
        {
          ll x;cin>>x;
          *((arr+i*m) + j)=x;
        }
}
// syntax for inp_mat inp_mat((ll *)arr,n,m);
int x2[]={+1,-1,+0,+0};
int y2[]={+0,+0,+1,-1};
char arr[1005][1005];int r,c;
int sr,sc,er,ec;
ll ff(int i,int j)
{
  return (i-1)*c+j;
}
int par[N];
int sz[N];
int root(int  x)
{
  while(par[x]!=x)
    {
        par[x] = par[par[x]] ; 
        x=par[x];
    }
    return x;
}
void join(int x,int y)
{
    int xx=root(x),yy=root(y);
    if(xx!=yy)
    {
      if(sz[xx]>sz[yy])
      swap(xx,yy);

      par[xx]=yy;
      sz[yy]+=sz[xx];
    }
}
vector< int>  graph[N];
bool vis[N];
int main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
       cin>>r>>c;
       mem(vis,false);
      cin>>sr>>sc>>er>>ec;
      int snode=ff(sr,sc);
      int enode=ff(er,ec);
      for(int i=1;i<=r;i++)
      for(int j=1;j<=c;j++)
      {cin>>arr[i][j];
        if(arr[i][j]=='.')
        {
          par[ff(i,j)]=ff(i,j);
          sz[ff(i,j)]=1;
        }
      }
      for(int i=1;i<=r;i++)
      {
        for(int j=1;j<=c;j++)
        {
            for(int k=0;k<4;k++)
            {
              int ii=i+x2[k],jj=j+y2[k];
              if(ii>=1 and ii<=r and jj>=1 and jj<=c)
              {
                if(arr[ii][jj]=='.' and arr[i][j]=='.')
                {
                  join(ff(ii,jj),ff(i,j));
                  // join(ff(i,j),ff(ii,jj));
                }
              }
            }
        }
      }

      for(int i=1;i<=r;i++)
      {
        for(int j=1;j<=c;j++)
        {
          if(arr[i][j]=='.')
          {
            par[ff(i,j)]=root(ff(i,j));
            // dbg(i);dbg(j);dbg(par[ff(i,j)]);
          }
        }
      }

      for(int i=1;i<=r;i++)
      {
        for(int j=1;j<=c;j++)
        {
          for(int ii=i-2;ii<=i+2;ii++)
          {
            for(int jj=j-2;jj<=j+2;jj++)
            {
              if(ii>=1 and ii<=r and jj>=1 and jj<=c)
              {
                if(arr[ii][jj]=='.' and arr[i][j]=='.')
                {
                  if(par[ff(ii,jj)]!=par[ff(i,j)])
                  {
                    graph[par[ff(ii,jj)]].pb(par[ff(i,j)]);
                    graph[par[ff(i,j)]].pb(par[ff(ii,jj)]);
                  }
                }
              }
            }
          }
        }
      }
      
      snode=par[snode];enode=par[enode];
      if(snode==enode)
      {
        cout<<0;
        return 0;
      }
      // dbg(snode);dbg(enode);
      queue< pair< int,int > > q;
      q.push({snode,0});
      vis[snode]=true;
      while(!q.empty())
      {
        int node=q.front().fi;
        // dbg(node);
        int v=q.front().se;
        if(node==enode)
        {
          cout<<v;
          return 0;
        }
        q.pop();
        for(auto child: graph[node])
        {
          if(!vis[child])
          {
            q.push({child,v+1});
            vis[child]=true;
          }
        }

      }
      cout<<"-1";


    



} 

Measured memory_bytes: 58820