#include <iostream>
#include <iosfwd>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cassert>
#include <cctype>
#include <climits>
#include <vector>
#include <bitset>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <deque>
#include <string>
#include <list>
#include <iterator>
#include <sstream>
#include <complex>
#include <fstream>
#include <functional>
#include <numeric>
#include <utility>
#include <algorithm>
#include <assert.h>
#include <unordered_map>
#include <random>
#include <ctime>
#include <chrono>

using namespace std;

long long t, n, m, u, v, q, k, p;
const int N = 1e6 + 500;
const long long mod = 1e9 + 7;
const long long INF = 1LL << 57;

long long arr[N];
vector <long long> dist[N];
vector <int> blocked[N];
set <int> row[N], col[N], revRow[N], revCol[N];
int xa, ya, xb, yb;
string str;

queue <pair <int, int> > Q;


int bfs(int srcX, int srcY, int distX, int distY) {
  dist[srcX][srcY] = 0;
  Q.push(make_pair(srcX, srcY));
  col[srcY].erase(srcX);
  row[srcX].erase(srcY);
  revCol[srcY].erase(-srcX);
  revRow[srcX].erase(-srcY);
  
  while (!Q.empty()) {
    pair <int, int> node = Q.front();
    if (node.first == distX and node.second == distY) break;
    Q.pop();
    vector <pair <int, int> > toErase;
    auto it = revRow[node.first].upper_bound(-node.second);
    while (it != revRow[node.first].end()) {
      int x = abs((*it));
      if (x < node.second - k or blocked[node.first][x]) break;
      else {
        dist[node.first][x] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (x)));
        Q.push(make_pair(node.first, (x)));
      }
      ++it;
    }
    auto it2 = row[node.first].upper_bound(node.second);
    while (it2 != row[node.first].end()) {
      if ((*it2) > node.second + k or blocked[node.first][*it2]) break;
      else {
        dist[node.first][*it2] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (*it2)));
        Q.push(make_pair(node.first, (*it2)));
      }
      ++it2;
    }
    auto it3 = col[node.second].upper_bound(node.first);
    while (it3 != col[node.second].end()) {
      if ((*it3) > node.first + k or blocked[*it3][node.second]) break;
      else {
        dist[*it3][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair((*it3), node.second));
        Q.push(make_pair((*it3), node.second));
      }
      ++it3;
    }
    auto it4 = revCol[node.second].upper_bound(-node.first);
    while (it4 != revCol[node.second].end()) {
      int x = abs((*it4));
      if (x < node.first - k or blocked[x][node.second]) break;
      else {
        dist[x][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(x, node.second));
        Q.push(make_pair(x, node.second));
      }
      ++it4;
    }
    for (auto it: toErase) {
      col[it.second].erase(it.first);
      row[it.first].erase(it.second);
      revRow[it.first].erase(-it.second);
      revCol[it.second].erase(-it.first);
    }
  }
  
  if (dist[distX][distY] == INF) return -1;
  else return dist[distX][distY];
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> k;
  cin >> xa >> ya >> xb >> yb;
  
  for (int i = 1; i <= n; ++i) {
    dist[i].resize(m + 1);
    blocked[i].resize(m + 1);
    for (int j = 1; j <= m; ++j) dist[i][j] = INF;
    for (int j = 1; j <= m; ++j) {
      row[i].insert(j);
      revRow[i].insert(-j);
    }
  }
  
  for (int j = 1; j <= m; ++j) for (int i = 1; i <= n; ++i) {
    col[j].insert(i);
    revCol[j].insert(-i);
  }
  
  for (int i = 1; i <= n; ++i) {
    cin >> str;
    for (int j = 0; j < str.size(); ++j) {
      if (str[j] == '@') {
        blocked[i][j+1] = true;
      }
    }
  }
  cout << bfs(xa, ya, xb, yb) << endl;
  
}





















Measured memory_bytes: 437984