//パソコンを閉じて、ごろんと寝っ転がっていたら思いついた。
//疲れを取って、脳内シミュレーション能力を回復させるのは時に重要。
//ところで、valueの略後であるvalにsをつけると、vals、バルス！！！
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#define rep(i, n) for(i = 0; i < n; i++)
#define rrep(i, n) for(i = n - 1; i >= 0; i--)
using namespace std;
typedef pair<int, int> P;

//未定義：2, 更新済み：1, 未更新：0を管理するために、セグメントツリーを書くのである。
struct SegMin {
	int DEPTH;			//深さは要素数と相談である
	vector<P> val;		//(value, pos)
	
	void init(int DEPTH) {
		this->DEPTH = DEPTH;
		val = vector<P>(1 << (DEPTH + 1), P(2, -1));
	}
	
	void update(int pos, int x) {
		pos += (1 << DEPTH) - 1;
		val[pos] = P(x, pos - (1 << DEPTH) + 1);
		while (pos > 0) {
			pos = (pos - 1) / 2;
			val[pos] = min(val[pos * 2 + 1], val[pos * 2 + 2]);
		}
	}
	
	P getMin(int l, int r, int a, int b, int id = 0) {
		if (a >= r || b <= l) { return P(2, -1); }
		if (l <= a && b <= r) { return val[id]; }
		P res1 = getMin(l, r, a, (a + b) / 2, id * 2 + 1);
		P res2 = getMin(l, r, (a + b) / 2, b, id * 2 + 2);
		return min(res1, res2);
	}
};

int h, w, K;
int sy, sx, gy, gx;
vector<string> s;
vector<SegMin> segRow;
vector<SegMin> segCol;
vector<vector<int>> dist;

int main() {
	int i, j;
	
	cin >> h >> w >> K;
	cin >> sy >> sx >> gy >> gx;
	sy--; sx--; gy--; gx--;
	
	s.resize(h);
	rep(i, h) {
		cin >> s[i];
	}
	
	vector<vector<int>> Lx(h, vector<int>(w));
	vector<vector<int>> Rx(h, vector<int>(w));
	vector<vector<int>> Uy(h, vector<int>(w));
	vector<vector<int>> Dy(h, vector<int>(w));
	
	rep(i, h) {
		rep(j, w) {
			if (s[i][j] == '@') {
				Lx[i][j] = j;
			}
			else {
				if (j == 0) Lx[i][j] = -1;
				else Lx[i][j] = Lx[i][j - 1];
			}
		}
	}
	
	rep(i, h) {
		rrep(j, w) {
			if (s[i][j] == '@') {
				Rx[i][j] = j;
			}
			else {
				if (j == w - 1) Rx[i][j] = w;
				else Rx[i][j] = Rx[i][j + 1];
			}
		}
	}
	
	rep(j, w) {
		rep(i, h) {
			if (s[i][j] == '@') {
				Uy[i][j] = i;
			}
			else {
				if (i == 0) Uy[i][j] = -1;
				else Uy[i][j] = Uy[i - 1][j];
			}
		}
	}
	
	rep(j, w) {
		rrep(i, h) {
			if (s[i][j] == '@') {
				Dy[i][j] = i;
			}
			else {
				if (i == h - 1) Dy[i][j] = h;
				else Dy[i][j] = Dy[i + 1][j];
			}
		}
	}
	
	int nw = 0;
	while (w > (1 << nw)) nw++;
	
	int nh = 0;
	while (h > (1 << nh)) nh++;
	
	segRow.resize(h);
	rep(i, h) {
		segRow[i].init(nw);
		rep(j, w) {
			segRow[i].update(j, 0);
		}
	}
	
	segCol.resize(w);
	rep(j, w) {
		segCol[j].init(nh);
		rep(i, h) {
			segCol[j].update(i, 0);
		}
	}
	
	dist.resize(h);
	rep(i, h) {
		dist[i].resize(w);
		rep(j, w) {
			dist[i][j] = -1;
		}
	}
	
	queue<P> que;
	que.push(P(sy, sx));
	dist[sy][sx] = 0;
	segRow[sy].update(sx, 1);
	segCol[sx].update(sy, 1);
	
	while (!que.empty()) {
		P now = que.front(); que.pop();
		int y = now.first;
		int x = now.second;
		
		//上下
		while (true) {
			int l = max(y - K, Uy[y][x] + 1);
			int r = min(y + K + 1, Dy[y][x]);
			P res = segCol[x].getMin(l, r, 0, 1 << segCol[x].DEPTH);
			if (res.first > 0) break;
			segCol[x].update(res.second, 1);
			segRow[res.second].update(x, 1);
			if (s[res.second][x] != '@') {
				dist[res.second][x] = dist[y][x] + 1;
				que.push(P(res.second, x));
			}
		}

		//左右
		while (true) {
			int l = max(x - K, Lx[y][x] + 1);
			int r = min(x + K + 1, Rx[y][x]);
			P res = segRow[y].getMin(l, r, 0, 1 << segRow[y].DEPTH);
			if (res.first > 0) break;
			segRow[y].update(res.second, 1);
			segCol[res.second].update(y, 1);
			if (s[y][res.second] != '@') {
				dist[y][res.second] = dist[y][x] + 1;
				que.push(P(y, res.second));
			}
		}
	}
	
	cout << dist[gy][gx] << endl;
	return 0;
}

Measured memory_bytes: 102688