#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int R, C, N;
cin >> R >> C >> N;
int sr, sc, gr, gc;
cin >> sr >> sc;
cin >> gr >> gc;
--sr; --sc; --gr; --gc;
vector<string> a(R);
for (int i = 0; i < R; i++) cin >> a[i];
auto id = [&](int r, int c) {
return r * C + c;
};
int V = R * C;
int S = id(sr, sc);
int G = id(gr, gc);
vector<unsigned char> reached(V, 0);
vector<int> active = {S};
vector<int> vis1(V, 0), vis2(V, 0), borderMark(V, 0), seedMark(V, 0);
int t1 = 1, t2 = 1, tb = 1, ts = 1;
vector<int> borderCells;
vector<int> component;
vector<int> seeds;
vector<int> nextActive;
vector<int> pref((R + 1) * (C + 1), 0);
auto pref_at = [&](int r, int c) -> int& {
return pref[r * (C + 1) + c];
};
int ans = 0;
while (true) {
deque<int> q;
component.clear();
++t1;
for (int x : active) {
if (vis1[x] == t1) continue;
vis1[x] = t1;
q.push_back(x);
}
while (!q.empty()) {
int v = q.front();
q.pop_front();
component.push_back(v);
int r = v / C;
int c = v % C;
if (r > 0) {
int u = v - C;
if (vis1[u] != t1 && (a[r - 1][c] == '.' || reached[u])) {
vis1[u] = t1;
q.push_back(u);
}
}
if (r + 1 < R) {
int u = v + C;
if (vis1[u] != t1 && (a[r + 1][c] == '.' || reached[u])) {
vis1[u] = t1;
q.push_back(u);
}
}
if (c > 0) {
int u = v - 1;
if (vis1[u] != t1 && (a[r][c - 1] == '.' || reached[u])) {
vis1[u] = t1;
q.push_back(u);
}
}
if (c + 1 < C) {
int u = v + 1;
if (vis1[u] != t1 && (a[r][c + 1] == '.' || reached[u])) {
vis1[u] = t1;
q.push_back(u);
}
}
}
for (int v : component) reached[v] = 1;
if (reached[G]) {
cout << ans << '\n';
return 0;
}
++tb;
borderCells.clear();
for (int v : component) {
int r = v / C;
int c = v % C;
if (r > 0) {
int u = v - C;
if (vis1[u] != t1 && a[r - 1][c] == '#' && borderMark[u] != tb) {
borderMark[u] = tb;
borderCells.push_back(u);
}
}
if (r + 1 < R) {
int u = v + C;
if (vis1[u] != t1 && a[r + 1][c] == '#' && borderMark[u] != tb) {
borderMark[u] = tb;
borderCells.push_back(u);
}
}
if (c > 0) {
int u = v - 1;
if (vis1[u] != t1 && a[r][c - 1] == '#' && borderMark[u] != tb) {
borderMark[u] = tb;
borderCells.push_back(u);
}
}
if (c + 1 < C) {
int u = v + 1;
if (vis1[u] != t1 && a[r][c + 1] == '#' && borderMark[u] != tb) {
borderMark[u] = tb;
borderCells.push_back(u);
}
}
}
if (borderCells.empty()) {
cout << -1 << '\n';
return 0;
}
fill(pref.begin(), pref.end(), 0);
for (int v : borderCells) {
int r = v / C;
int c = v % C;
pref_at(r + 1, c + 1) = 1;
}
for (int r = 1; r <= R; r++) {
int rowBase = r * (C + 1);
int prevBase = (r - 1) * (C + 1);
for (int c = 1; c <= C; c++) {
pref[rowBase + c] += pref[rowBase + c - 1] + pref[prevBase + c] - pref[prevBase + c - 1];
}
}
++ts;
seeds.clear();
for (int r = 0; r < R; r++) {
int r1 = max(0, r - (N - 1));
int r2 = min(R - 1, r + (N - 1));
for (int c = 0; c < C; c++) {
int c1 = max(0, c - (N - 1));
int c2 = min(C - 1, c + (N - 1));
int sum = pref_at(r2 + 1, c2 + 1) - pref_at(r1, c2 + 1) - pref_at(r2 + 1, c1) + pref_at(r1, c1);
if (sum > 0) {
int v = id(r, c);
seedMark[v] = ts;
seeds.push_back(v);
}
}
}
++t2;
deque<int> q2;
nextActive.clear();
for (int v : seeds) {
if (vis2[v] == t2) continue;
vis2[v] = t2;
q2.push_back(v);
}
while (!q2.empty()) {
int v = q2.front();
q2.pop_front();
if (!reached[v]) nextActive.push_back(v);
int r = v / C;
int c = v % C;
if (r > 0) {
int u = v - C;
if (vis2[u] != t2 && a[r - 1][c] == '.') {
vis2[u] = t2;
q2.push_back(u);
}
}
if (r + 1 < R) {
int u = v + C;
if (vis2[u] != t2 && a[r + 1][c] == '.') {
vis2[u] = t2;
q2.push_back(u);
}
}
if (c > 0) {
int u = v - 1;
if (vis2[u] != t2 && a[r][c - 1] == '.') {
vis2[u] = t2;
q2.push_back(u);
}
}
if (c + 1 < C) {
int u = v + 1;
if (vis2[u] != t2 && a[r][c + 1] == '.') {
vis2[u] = t2;
q2.push_back(u);
}
}
}
if (nextActive.empty()) {
cout << -1 << '\n';
return 0;
}
active.swap(nextActive);
ans++;
}
return 0;
}