#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key
 
typedef long long ll;
typedef pair<ll,ll> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> pbds;

vector<set<int> > rows;
vector<set<int> > cols;
int n,m,k; 
vector<string> grid;

int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};

vector<vi> dist;
const int INF = int(1e9);

void add(int i, int j)
{
	rows[i].insert(j);
	cols[j].insert(i);
}

void rem(int i, int j)
{
	rows[i].erase(j);
	cols[j].erase(i);
}

vector<vi> L;
vector<vi> R;
vector<vi> U;
vector<vi> D;

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin>>n>>m>>k;
	int sx,sy,ex,ey;
	cin>>sx>>sy>>ex>>ey;
	sx--; sy--; ex--; ey--;
	rows.resize(n); cols.resize(m);
	dist.resize(n);
	for(int i=0;i<n;i++) dist[i].assign(m,INF);
	for(int i=0;i<n;i++)
	{
		string s; cin>>s;
		grid.pb(s);
		for(int j=0;j<m;j++)
		{
			if(s[j]=='.')
			{
				add(i,j);
			}
		}
	}
	L.resize(n); R.resize(n); U.resize(n); D.resize(n);
	for(int i=0;i<n;i++)
	{
		L[i].resize(m);R[i].resize(m);U[i].resize(m);D[i].resize(m);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(grid[i][j]!='.') L[i][j]=-1;
			else
			{
				if(j>0&&L[i][j-1]!=-1) L[i][j]=L[i][j-1];
				else L[i][j]=j;
			}
		}
		for(int j=m-1;j>=0;j--)
		{
			if(grid[i][j]!='.') R[i][j]=-1;
			else
			{
				if(j<m-1&&R[i][j+1]!=-1) R[i][j]=R[i][j+1];
				else R[i][j]=j;
			}
		}
	}
	for(int j=0;j<m;j++)
	{
		for(int i=0;i<n;i++)
		{
			if(grid[i][j]!='.') U[i][j]=-1;
			else
			{
				if(i>0&&U[i-1][j]!=-1) U[i][j]=U[i-1][j];
				else U[i][j]=i;
			}
		}
		for(int i=n-1;i>=0;i--)
		{
			if(grid[i][j]!='.') D[i][j]=-1;
			else
			{
				if(i<n-1&&D[i+1][j]!=-1) D[i][j]=D[i+1][j];
				else D[i][j]=i;
			}
		}
	}
	queue<ii> q;
	q.push({sx,sy});
	dist[sx][sy]=0; rem(sx,sy);
	while(!q.empty())
	{
		int x=q.front().fi; int y=q.front().se;
		q.pop();
		//L
		{
			int miny = max(y-k,L[x][y]);
			auto it = rows[x].lower_bound(y);
			if(it!=rows[x].begin())
			{
				it--;
				//first <= y
				vector<ii> removals;
				while((*it)>=miny)
				{
					removals.pb({x,(*it)});
					if(it==rows[x].begin()) break;
					it--;
				}
				for(ii sq:removals)
				{
					dist[sq.fi][sq.se]=dist[x][y]+1;
					q.push(sq);
					rem(sq.fi,sq.se);
				}
			}
		}
		//R
		{
			int maxy = min(y+k,R[x][y]);
			auto it = rows[x].upper_bound(y);
			if(it!=rows[x].end())
			{
				//first > y
				vector<ii> removals;
				while((*it)<=maxy)
				{
					removals.pb({x,(*it)});
					it++;
					if(it==rows[x].end()) break;
				}
				for(ii sq:removals)
				{
					dist[sq.fi][sq.se]=dist[x][y]+1;
					q.push(sq);
					rem(sq.fi,sq.se);
				}
			}
		}
		//U
		{
			int minx = max(x-k,U[x][y]);
			auto it = cols[y].lower_bound(x);
			if(it!=cols[y].begin())
			{
				it--;
				//first <= y
				vector<ii> removals;
				while((*it)>=minx)
				{
					removals.pb({(*it),y});
					if(it==cols[y].begin()) break;
					it--;
				}
				for(ii sq:removals)
				{
					dist[sq.fi][sq.se]=dist[x][y]+1;
					q.push(sq);
					rem(sq.fi,sq.se);
				}
			}
		}
		//D
		{
			int maxx = min(x+k,D[x][y]);
			auto it = cols[y].lower_bound(x);
			if(it!=cols[y].end())
			{
				//first <= y
				vector<ii> removals;
				while((*it)<=maxx)
				{
					removals.pb({(*it),y});
					it++;
					if(it==cols[y].end()) break;
				}
				for(ii sq:removals)
				{
					dist[sq.fi][sq.se]=dist[x][y]+1;
					q.push(sq);
					rem(sq.fi,sq.se);
				}
			}
		}
	}
	if(dist[ex][ey]>=INF) dist[ex][ey]=-1;
	cout<<dist[ex][ey]<<'\n';
}


Measured memory_bytes: 164028