#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\n"
#define die(cond) if (cond) for (;;){}
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template<typename T> inline bool mineq(T& a, T b) { return (a > b) ? (a = b, 1) : 0; }
template<typename T> inline bool maxeq(T& a, T b) { return (a < b) ? (a = b, 1) : 0; }

inline void solve(), read();
const string file = "";

int main() {
#ifndef _DEBUG
	if (file != "") {
		freopen((file + ".in").c_str(), "r", stdin);
		freopen((file + ".out").c_str(), "w", stdout);
	}
#endif
	fast;
	read();
	solve();
	return 0;
}

pll operator + (pll a, pll b) {
	return { a.ft + b.ft, a.sd + b.sd };
}

ll n, m, k;
vector<vll> a;
pll s, t;
vector<pll> dirs = { {0, -1}, {0, +1}, {-1, 0}, {+1, 0} };
vector<sll> vis1, vis2;

ll good(ll x, ll y) {
	return 0 <= x && x < n && 0 <= y && y < m && a[x][y];
}

ll bfs(pll s, pll t) {
	vis1.resize(n);
	vis2.resize(m);
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m; j++) {
			vis1[i].insert(j);
			vis2[j].insert(i);
		}
	}
	vis1[s.ft].erase(s.sd);
	vis2[s.sd].erase(s.ft);
	queue<pll> q;
	map<pll, ll> d;
	q.push(s);
	d[s] = 0;
	while (!q.empty()) {
		pll p = q.front();
		q.pop();
		sll::iterator i1;
		i1 = vis1[p.ft].lower_bound(p.sd);
		for (auto it = i1; it != vis1[p.ft].end() && *it <= p.sd + k; ) {
			if (!a[p.ft][*it]) {
				break;
			}
			d[{p.ft, *it}] = d[p] + 1;
			q.push({ p.ft, *it });
			vis2[*it].erase(p.ft);
			it = vis1[p.ft].erase(it);
		}
		i1 = vis1[p.ft].lower_bound(p.sd);
		if (i1 != vis1[p.ft].begin()) {
			--i1;
		}
		for (auto it = i1; it != vis1[p.ft].end() && *it < p.sd && p.sd - k <= *it;) {
			if (!a[p.ft][*it]) {
				break;
			}
			d[{p.ft, *it}] = d[p] + 1;
			q.push({ p.ft, *it });
			vis2[*it].erase(p.ft);
			it = vis1[p.ft].erase(it);
			if (it == vis1[p.ft].begin()) {
				break;
			}
			--it;
		}
		i1 = vis2[p.sd].lower_bound(p.ft);
		for (auto it = i1; it != vis2[p.sd].end() && *it <= p.ft + k; ) {
			if (!a[*it][p.sd]) {
				break;
			}
			d[{*it, p.sd}] = d[p] + 1;
			q.push({ *it, p.sd });
			vis1[*it].erase(p.sd);
			it = vis2[p.sd].erase(it);
		}
		i1 = vis2[p.sd].lower_bound(p.ft);
		if (i1 != vis2[p.sd].begin()) {
			--i1;
		}
		for (auto it = i1; i1 != vis2[p.sd].end() && *it < p.ft && p.ft - k <= *it;) {
			if (!a[*it][p.sd]) {
				break;
			}
			d[{*it, p.sd}] = d[p] + 1;
			q.push({ *it, p.sd });
			vis1[*it].erase(p.sd);
			it = vis2[p.sd].erase(it);
			if (it == vis2[p.sd].begin()) {
				break;
			}
			--it;
		}
	}
	if (!d.count(t)) {
		return -1;
	}
	return d[t];
}

inline void solve() {
	ll ans = bfs(s, t);
	cout << ans << endl;
}

inline void read() {
	cin >> n >> m >> k;
	a.resize(n, vll(m, 0));
	cin >> s.ft >> s.sd >> t.ft >> t.sd;
	--s.ft, --s.sd, --t.ft, --t.sd;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j < m; j++) {
			char c;
			cin >> c;
			if (c == '.') {
				a[i][j] = 1;
			}
		}
	}
}

Measured memory_bytes: 147740