unittest
{
	assert( [ "4 4", "1 1", "4 4", "..#.", "..#.", ".#..", ".#.." ].solve == 1 );
	assert( [ "4 4", "1 4", "4 1", ".##.", "####", "####", ".##." ].solve == -1 );
	assert( [ "4 4", "2 2", "3 3", "....", "....", "....", "...." ].solve == 0 );
	assert( [ "4 5", "1 2", "2 5", "#.###", "####.", "#..##", "#..##" ].solve == 2 );
}



import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto h = 0L;
	auto w = 0L;
	input.front.formattedRead!"%s %s"( h, w );
	auto cy = 0L;
	auto cx = 0L;
	input.popFront;
	input.front.formattedRead!"%s %s"( cy, cx );
	cy--;
	cx--;
	auto dy = 0L;
	auto dx = 0L;
	input.popFront;
	input.front.formattedRead!"%s %s"( dy, dx );
	dy--;
	dx--;
	auto sss = new dchar[][]( h, w );
	foreach( ref ss; sss )
	{
		input.popFront;
		ss = input.front.to!( dchar[] );
	}
	
	auto dss = dijkstraGridEx( sss, cy, cx );
	return ( dss[ dy ][ dx ] == long.max ) ? -1 : dss[ dy ][ dx ];
}

// 正のグリッドマップの始点指定最短経路探索（ダイクストラ法）
auto dijkstraGridEx( T, T W = '#' )( T[][] css, long sy, long sx )
{
	auto dss = new long[][]( css.length, css[ 0 ].length );
	foreach( ref ds; dss ) ds[] = long.max;
	dss[ sy ][ sx ] = 0;
	auto uss = new bool[][]( css.length, css[ 0 ].length );
	
	auto queue = heapify!( ( a, b ) => b[ 2 ] < a[ 2 ] )( [ tuple( sy, sx, dss[ sy ][ sx ] ) ] );
	while( !queue.empty )
	{
		auto fy = queue.front[ 0 ];
		auto fx = queue.front[ 1 ];
		auto fd = queue.front[ 2 ];
		queue.popFront();
		
		if( uss[ fy ][ fx ] ) continue;
		uss[ fy ][ fx ] = true;
		
		// 徒歩
		foreach( p; [ [ -1, 0 ], [ 1, 0 ], [ 0, -1 ], [ 0, 1 ] ] )
		{
			auto ty = fy + p[ 0 ];
			auto tx = fx + p[ 1 ];
			
			if( ty < 0 || css.length <= ty || tx < 0 || css[ ty ].length <= tx ) continue;		// マップ外
			if( css[ ty ][ tx ] == W ) continue;												// 壁
			if( dss[ ty ][ tx ] <= fd ) continue;												// 探索済
			
			dss[ ty ][ tx ] = fd;
			queue.insert( tuple( ty, tx, fd ) );
		}
		
		// ワープ
		foreach( py; -2L .. 3L )
		{
			foreach( px; -2L .. 3L )
			{
				auto ty = fy + py;
				auto tx = fx + px;
				auto td = fd + 1;
				
				if( ty < 0 || css.length <= ty || tx < 0 || css[ ty ].length <= tx ) continue;		// マップ外
				if( css[ ty ][ tx ] == W ) continue;												// 壁
				if( dss[ ty ][ tx ] <= td ) continue;												// 探索済
				
				dss[ ty ][ tx ] = td;
				queue.insert( tuple( ty, tx, td ) );
			}
		}
	}
	return dss;
}
