#include<bits/stdc++.h>
 // #include <ext/pb_ds/tree_policy.hpp>
 // #include <ext/pb_ds/assoc_container.hpp>
 #include<chrono>
  using namespace std;
   using namespace std::chrono;      
  // using namespace __gnu_pbds; 
 #define fastio     ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
 #define fi         first
 #define se         second
 #define int         long long 
 #define pb         push_back
 #define emp        emplace_back
 #define vv(x)      vector<x>
 #define mp(x,y)    map<x,y>
 #define dq(x)      deque<x>
 #define pql(x)     priority_queue<x>
 #define pqs(x)     priority_queue<x,vv(x),greater<x> >
 //#define M          1000000007
 #define forf(i,a,b) for(int i=a;i<b;i++)
 #define it(x)      x::iterator
 #define ll         long long 
 #define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
 #define time__(d)  for(long blockTime = 0; (blockTime == 0 ? (blockTime=clock()) != 0 : false); debug("%s time : %.4fs", d, (double)(clock() - blockTime) / CLOCKS_PER_SEC))
 #define vii        vector<int>
 #define big        1e12
 #define sm         -2e18
 #define mkr        make_pair
 #define vpi        vector<pair<int,int> >
 #define pii        pair<int,int>
 #define rng        500005
 #define sz(x)      (int)x.size()
 #define rv(x)      reverse(x.begin(),x.end())
 #define out(x)     cout<<x.fi<<" "<<x.se<<endl;
#define MEM(x,val) memset(x,val,sizeof(x))

 // typedef tree<pii, null_type, less<pii>, rb_tree_tag,  
 //            tree_order_statistics_node_update>  odst; 


void pr_init()
{
   
    #ifndef ONLINE_JUDGE
    freopen("gin.txt", "r", stdin);
   // freopen("output.txt", "w", stdout);
   
    #endif
}


const int Mxn = 1e3+2;
char mat[Mxn][Mxn];
int h,w,ch,cw,dh,dw;
vector<vector<int> > dp;  
int check(int x,int y,int vl)
{
  if(x<0||x>=h||y<0||y>=w) return 0;

  if(mat[x][y]=='#') return 0;
  
  if(dp[x][y]<=vl) return 0;
  return 1; 
}   
void solve()
{
  
  cin >> h >> w >> ch >> cw >> dh >> dw;
  
  dp.assign(h,vector<int>(w,big));

  forf(i,0,h)
  {
    forf(j,0,w)
    {
      cin >> mat[i][j];
    }
  }
  ch--,cw--,dh--,dw--;
  
  if(mat[ch][cw]=='#' || mat[dh][dw]=='#')
  {
    cout<<"-1\n";
    return;
  }
  dp[ch][cw] = 0;

  queue<pair<int,int> > pq;
  pq.push({ch,cw});
  
  while(pq.size()>0)
  {
    //cout<<pq.size()<<"\n";
    queue<pair<int,int>>temp;
    while(pq.size()>0)
    
    {
    int x = pq.front().fi , y = pq.front().se;
    temp.push({x,y});
    pq.pop();
    if(check(x+1,y,dp[x][y])) dp[x+1][y] = dp[x][y] , pq.push({x+1,y});
    if(check(x-1,y,dp[x][y])) dp[x-1][y] = dp[x][y] , pq.push({x-1,y});
    if(check(x,y+1,dp[x][y])) dp[x][y+1] = dp[x][y] , pq.push({x,y+1});
    if(check(x,y-1,dp[x][y])) dp[x][y-1] = dp[x][y] , pq.push({x,y-1});
    
    }
    //using magic
    while(temp.size()>0)
    
    {
       int x = temp.front().fi , y = temp.front().se;
    temp.pop();
   
      for(int i=x-2;i<=x+2;i++)
    {
      for(int j=y-2;j<=y+2;j++)
      {
         if(check(i,j,dp[x][y]+1)) dp[i][j] = dp[x][y]+1 , pq.push({i,j});
      }
    }
  }

  }
  // for(int i=0;i<h;i++)
  // {
  //   for(int j=0;j<w;j++)
  //   {
  //     cout<<dp[i][j]<<" ";
  //   }
  //   cout<<"\n";
  // }

  int an = dp[dh][dw];
  if(an>=big) an=-1;
  cout<<an;
}

int32_t main()
{
  pr_init();
  fastio;
  auto start = high_resolution_clock::now(); 
  solve(); 
  auto stop = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>(stop - start); 
  
    // cout << "Time taken by function: "
    //      << duration.count() << " microseconds" << endl; 

  return 0;
}

Measured memory_bytes: 12644