#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

#define REP(i,n) for( (i)=0 ; (i)<(n) ; (i)++ )
#define rep(i,x,n) for( (i)=(x) ; (i)<(n) ; (i)++ )
#define REV(i,n) for( (i)=(n) ; (i)>=0 ; (i)-- )
#define FORIT(it,x) for( (it)=(x).begin() ; (it)!=(x).end() ; (it)++ )
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define rforeach(it,c) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();++it)
#define foreach2d(i, j, v) foreach(i,v) foreach(j,*i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define SZ(x) ((int)(x).size())
#define MMS(x,n) memset(x,n,sizeof(x))
#define mms(x,n,s) memset(x,n,sizeof(x)*s)
#define pb push_back
#define mp make_pair
#define NX next_permutation
#define UN(x) sort(all(x)),x.erase(unique(all(x)),x.end())
#define CV(x,n) count(all(x),(n))
#define FIND(x,n) find(all(x),(n))-(x).begin()
#define ACC(x) accumulate(all(x),0)
#define PPC(x) __builtin_popcountll(x)
#define LZ(x) __builtin_clz(x)
#define TZ(x) __builtin_ctz(x)
#define mxe(x) *max_element(all(x))
#define mne(x) *min_element(all(x))
#define low(x,i) lower_bound(all(x),i)
#define upp(x,i) upper_bound(all(x),i)
#define NXPOW2(x) (1ll << ((int)log2(x)+1))
#define PR(x) cout << #x << " = " << (x) << endl ;

typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef pair<int, int> pii;
typedef tuple<int, int, int> tiii;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const int OO = (int) 2e9;
const double eps = 1e-9;

const int N = 1e6 + 6;

int n, m, k;
vector<string> a;
int p[2][2];
vector<vector<double>> dist[4];
vector<vector<double>> step[4];
int di[] = { -1, 0, 0, 1 };
int dj[] = { 0, -1, 1, 0 };

bool ok(int i, int j) {
	return i >= 0 && i < n && j >= 0 && j < m && a[i][j] == '.';
}

int dij() {
	priority_queue<pair<tiii, pii>, vector<pair<tiii, pii>>, greater<pair<tiii, pii>>> Q;
	for (int i = 0; i < 4; i++) {
		Q.push( { { 0, 0, i }, { p[0][0], p[0][1] } });
		dist[i][p[0][0]][p[0][1]] = 0;
		step[i][p[0][0]][p[0][1]] = 0;
	}
	while (!Q.empty()) {
		int c = get<0>(Q.top().first);
		int s = get<1>(Q.top().first);
		int d = get<2>(Q.top().first);
		int x = Q.top().second.first;
		int y = Q.top().second.second;
		Q.pop();
		if (c != dist[d][x][y] && s != step[d][x][y])
			continue;
		if (x == p[1][0] && y == p[1][1])
			return dist[d][x][y] + bool(step[d][x][y]);
		int nx = x + di[d];
		int ny = y + dj[d];
		int ns = s + 1;
		int nc = c;
		if (ns == k)
			ns = 0, nc++;
		if (ok(nx, ny)) {
			if (dist[d][nx][ny] > nc || (dist[d][nx][ny] == nc && step[d][nx][ny] > ns)) {
				dist[d][nx][ny] = nc;
				step[d][nx][ny] = ns;
				Q.push( { { nc, ns, d }, { nx, ny } });
			}
		}
		for (int nd = 0; nd < 4; nd++) {
			if (nd == d)
				continue;
			nc = (s > 0) ? c + 1 : c;
			ns = 0;
			if (dist[nd][x][y] > nc || (dist[nd][x][y] == nc && step[nd][x][y] > ns)) {
				dist[nd][x][y] = nc;
				step[nd][x][y] = ns;
				Q.push( { { nc, ns, nd }, { x, y } });
			}
		}
	}
	return -1;
}

int main() {
	std::ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
//	freopen("in.txt", "rt", stdin);
//	freopen("out.txt", "wt", stdout);
#endif
	cin >> n >> m >> k;
	a.resize(n);
	for (int i = 0; i < 4; i++)
		dist[i].resize(n), step[i].resize(n);
	cin >> p[0][0] >> p[0][1];
	cin >> p[1][0] >> p[1][1];
	p[0][0]--, p[0][1]--, p[1][0]--, p[1][1]--;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		for (int j = 0; j < 4; j++)
			dist[j][i].resize(m, OO), step[j][i].resize(m, OO);
	}
	cout << dij() << endl;
	return 0;
}


Measured memory_bytes: 77496