/*Bismillahir Rahmanir Rahim*///{
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <bitset>		//UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>		//do setprecision
#include <ctime>
#include <complex>
#include <chrono>
#include<functional>
#include<unordered_map>
using namespace std;

using ll = long long; using ull = unsigned long long; using ld = long double;
const ll llinf = (1ll << 61) - 1; const double eps = 1e-6, ldeps = 1e-9;
struct Dbg {
	static constexpr auto &os = cout;   // replace by cerr in interactive.
	template<class C> static auto o(C *x)->decltype(os << *x, 0);
	template<class C> static char o(...);
	template<class C> typename enable_if<sizeof o<C>(0) != 1, Dbg&>::type operator<<(const C &x) { os << x; return *this; }
	template<class C> Dbg &dump(C b, C e) {
		for (struct { C i; int j; } i = { (*this << "\n[",b),0 }; i.i != e and i.j < 26; i.i++, i.j++) *this << ", " + 2 * (i.i == b) << *i.i;
		return *this << ']';
	}
	template<class C> typename enable_if<sizeof o<C>(0) == 1, Dbg&>::type operator<<(const C &x) {
		return dump(begin(x), end(x));
	}
	template<class C, size_t X> typename enable_if<!is_same<C, const char>::value, Dbg&>::type operator<<(C(&x)[X]) {
		return dump(begin(x), end(x));
	}
	template<class B, class C> Dbg &operator<<(const pair<B, C> &x) { return *this << '{' << x.first << ", " << x.second << '}'; }
	Dbg &operator<<(ostream&(*x)(std::ostream&)) { os << x; return *this; }
} dbg;
void err(istringstream *iss) { delete iss; }
template<class C, class... Args> void err(istringstream *iss, const C &val, const Args &... args) {
	string name; *iss >> name; if (name.back() == ',') name.pop_back();
	dbg << name << " = " << val << "; ", err(iss, args...);
}
#define sl(a) int(strlen(a))
#define sz(a) int(a.size())
int T, Q, cn;//}
const int inf = 1000000007, mxn = 1000005;

string grid[mxn];
int h, w, K, xy[2][2];
vector<vector<int> > lvl;
vector<pair<int, int> > nlvl[mxn];
int cntDir = 4, dirr[] = { 1, 0, 0, -1 }, dirc[] = { 0, -1, 1, 0 };
inline bool invalid(int vr, int vc) {
	return vr < 0 || vr >= h || vc < 0 || vc >= w || grid[vr][vc] == '@';
}

static std::function<bool(pair<int, int>, pair<int, int>)> ops[6] = {
	{[](const pair<int, int> &l, const pair<int, int> &r)->bool {return l.first > r.first; }},
	{[](const pair<int, int> &l, const pair<int, int> &r)->bool {return l.second < r.second; }},
	{[](const pair<int, int> &l, const pair<int, int> &r)->bool {return l.second > r.second; }},
	{[](const pair<int, int> &l, const pair<int, int> &r)->bool {return l.first < r.first; }}
};

void bfs() {
	lvl[xy[0][0]][xy[0][1]] = 0;
	nlvl[0].push_back({ xy[0][0], xy[0][1] });
	for (int i = 0; i < mxn; i++) {
		if (nlvl[i].empty()) return;
		int sz = sz(nlvl[i]);
		for (int j = 0; j < cntDir; j++) {
			sort(begin(nlvl[i]), end(nlvl[i]), ops[j]);
			for (auto &node : nlvl[i]) {
				int ur = node.first, uc = node.second, vr = ur, vc = uc;
				for (int l = 1; l <= K; l++) {
					vr += dirr[j], vc += dirc[j];
					if (invalid(vr, vc) or lvl[vr][vc] <= lvl[ur][uc]) break;
					if (lvl[vr][vc] == lvl[ur][uc] + 1) continue;
					lvl[vr][vc] = lvl[ur][uc] + 1;
					nlvl[lvl[vr][vc]].push_back({ vr, vc });
				}
			}
		}
	}
}

signed main() {
	cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cout.precision(11), cout.setf(ios::fixed);
	cin >> h >> w >> K;
	lvl.resize(h, vector<int>(w, inf));
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			cin >> xy[i][j];
			--xy[i][j];
		}
	}
	for (int i = 0; i < h; i++) {
		cin >> grid[i];
	}
	bfs();
	if (lvl[xy[1][0]][xy[1][1]] == inf) return cout << "-1\n", 0;
	cout << lvl[xy[1][0]][xy[1][1]] << '\n';
}

Measured memory_bytes: 68528