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



import std.algorithm;
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;
	auto k = 0L;
	input.front.formattedRead!"%s %s %s"( h, w, k );
	input.popFront;
	auto sy = 0L;
	auto sx = 0L;
	auto gy = 0L;
	auto gx = 0L;
	input.front.formattedRead!"%s %s %s %s"( sy, sx, gy, gx );
	auto css = new dchar[][]( h, w );
	foreach( ref cs; css )
	{
		input.popFront;
		cs = input.front.to!( dchar[] );
	}
	sy--;
	sx--;
	gy--;
	gx--;
	
	auto dsss = dijkstraGridEx( css, k, sy, sx );
	auto ans = dsss[ gy ][ gx ].reduce!min;
	return ( ans == long.max ) ? -1 : ( ans + k - 1 ) / k;
}

// 正のグリッドマップの始点指定最短経路探索（ダイクストラ法）
auto dijkstraGridEx( T, T W = '@' )( T[][] css, long k, long sy, long sx )
{
	import std.container.binaryheap;
	
	auto dsss = new long[][][]( css.length, css[ 0 ].length, 4 );
	foreach( ref dss; dsss )
	{
		foreach( ref ds; dss ) ds[] = long.max;
	}
	dsss[ sy ][ sx ][] = 0;
	auto usss = new bool[][][]( css.length, css[ 0 ].length, 4 );
	
	auto queue = heapify!( ( a, b ) => b[ 3 ] < a[ 3 ] )( new Tuple!( long, long, long, long )[ css.length * css[ 0 ].length * 4 ], 0 );
	queue.insert( tuple( sy, sx, 0L, 0L ) );
	queue.insert( tuple( sy, sx, 1L, 0L ) );
	queue.insert( tuple( sy, sx, 2L, 0L ) );
	queue.insert( tuple( sy, sx, 3L, 0L ) );
	while( !queue.empty )
	{
		auto fy = queue.front[ 0 ];
		auto fx = queue.front[ 1 ];
		auto ff = queue.front[ 2 ];
		auto fd = queue.front[ 3 ];
		queue.popFront();
		
		if( usss[ fy ][ fx ][ ff ] ) continue;
		usss[ fy ][ fx ][ ff ] = true;
		
		foreach( i, p; [ [ -1, 0 ], [ 1, 0 ], [ 0, -1 ], [ 0, 1 ] ] )
		{
			auto ty = 0L;
			auto tx = 0L;
			auto td = 0L;
			auto tf = i.signed;
			
			if( ff == tf )
			{
				// 前進
				ty = fy + p[ 0 ];
				tx = fx + p[ 1 ];
				td = fd + 1;
				
				if( ty < 0 || css.length <= ty || tx < 0 || css[ ty ].length <= tx ) continue;		// マップ外
				if( css[ ty ][ tx ] == W ) continue;												// 壁
			}
			else
			{
				// 方向転換
				ty = fy;
				tx = fx;
				td = ( fd + k - 1 ) / k * k;
			}
			
			if( dsss[ ty ][ tx ][ tf ] <= td ) continue;
			
			dsss[ ty ][ tx ][ tf ] = td;
			queue.insert( tuple( ty, tx, tf, td ) );
		}
	}
	return dsss;
}
