#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
using namespace std;


#define LETS_GET_SCHWIFTY ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);  
#define ff              first
#define ss              second
#define int             long long
#define ll              long long
#define pb              push_back
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zerobits(x)      __builtin_ctzll(x)
#define mod             998244353
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define vpii            vector<pair<int,int> >
#define all(x)          x.begin(),x.end()
#define matrixprint(arr,a,b,c,d) for(int i=a;i<=c;i++){for(int j=b;j<=d;j++){cout<<arr[i][j]<<" ";}cout<<"\n";}
#define show(arr,x,y)   for(int i=x;i<=y;i++){cout<<arr[i]<<" ";}cout<<"\n"
#define sz(x)           (int)x.size()
#define db(x)           cout<<x<<"\n";

const int N = 2e5 + 5;

#define TRACE
#ifdef TRACE
#define deb(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
    cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}
#else
#define deb(...)
#endif

	
//////////////////////////////code//////////////////////////////

void solve()
{
  //  cout << "-------------------" << "\n";
    
    int n,m;
    cin>>n>>m;
    
    int src1,src2,tar1,tar2;
    
    cin>>src1>>src2>>tar1>>tar2;
    
    char arr[n+1][m+1];
    
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      cin>>arr[i][j];
      
    map<pii,int>mp;
    
    mp[{0,-1}]++,mp[{0,1}]++,mp[{-1,0}]++,mp[{1,0}]++;
    
    set<pair<int,pii> > s;
    
    s.insert({0,{src1,src2}});
    
    int dis[1001][1001];
    
    memset(dis,-1,sizeof(dis));
    
    if(arr[src1][src2] == '#')
    {
        db(-1)
        return;
    }
    
    while(!s.empty())
    {
        auto it = s.begin();
        
       int x = it->ss.ff,y = it->ss.ss;
       
       int now = it->ff;
        
      //  deb(x,y,now); 
        
        s.erase(it);
        
        if(dis[x][y]==-1)
        {
            dis[x][y] = now;
            
            for(int i=-2;i<=2;i++)
             for(int j=-2;j<=2;j++)
             {
                 int nx = x + i , ny = y + j;
                 
                 if(nx>=1 && nx<=n && ny>=1 && ny<=m && arr[nx][ny] == '.')
                 {
                     if(mp.count({i,j}))
                     {
                         s.insert({0+now,{nx,ny}});
                     }
                     else
                     {
                         s.insert({1+now,{nx,ny}});
                     }
                 }
             }
        }
    }
    
    
    db(dis[tar1][tar2])
  
 

 //   cout << "-------------------" << "\n";

}

int32_t main()
{

    LETS_GET_SCHWIFTY;

    int t = 1;
   // cin >> t;

    while (t--)
        solve();

}

// check out for following mistakes-
// if using pb operation on vector and then trying to access index..check if sizeof that vec could remain 0 only
// is using prime sieve make sure it fits
// when using factorial template or combinatorics make sure that you edit fillfac fun values and array values


Measured memory_bytes: 13480