#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<iomanip>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef pair<ll,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(ll i=0;i<x;i++)
#define repn(i,x) for(ll i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

const int MAX = 510000;
const int MOD = 1000000007;

// 四方向への移動ベクトル
const ll dx[4] = {1, 0, -1, 0};
const ll dy[4] = {0, 1, 0, -1};

int main(){
  ll H , W , K; cin >> H >> W >> K;
  ll sx , sy , gx , gy; cin >> sx >> sy >> gx >> gy; sx--; sy--; gx--; gy--;
  vector<string> field(H);
  rep(i,H) cin >> field[i];

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int> > d(H, vector<int>(W, -1));
  d[sx][sy] = 0; // スタートを 0 に


  // そもそもいけない時はKでの探索しない
  queue<P> que1;
  que1.pu(mp(sx, sy));
  while(!que1.empty()){
    pair<ll, ll> current_pos = que1.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    que1.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
        ll next_x = x + dx[direction];
        ll next_y = y + dy[direction];
        if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W) continue; // 場外アウトならダメ
        if (field[next_x][next_y] == '@') continue; // 壁はダメ

        // まだ見ていない頂点なら push
        if (d[next_x][next_y] == -1){
            que1.push(make_pair(next_x, next_y));
            d[next_x][next_y] = d[x][y] + 1; // (next_x, next_y) の距離も更新
        }
    }
  }
  if(d[gx][gy] == -1){
    cout << -1 << endl;
    return 0;
  }

  // 各セルの最短距離 (訪れていないところは -1 としておく)
  vector<vector<int> > dist(H, vector<int>(W, -1));
  dist[sx][sy] = 0; // スタートを 0 に


  queue<P> que;
  que.pu(mp(sx, sy));
  while(!que.empty()){
    pair<ll, ll> current_pos = que.front(); // キューの先頭を見る (C++ ではこれをしても pop しない)
    ll x = current_pos.first;
    ll y = current_pos.second;
    if(dist[x][y] > d[gx][gy]) break;
    que.pop(); // キューから pop を忘れずに

    // 隣接頂点を探索
    for (ll direction = 0; direction < 4; ++direction) {
      repn(j , K){
        ll next_x = x + j * dx[direction];
        ll next_y = y + j * dy[direction];
        if (next_x < 0 || next_x >= H || next_y < 0 || next_y >= W) break; // 場外アウトならダメ
        if (field[next_x][next_y] == '@') break; // 壁はダメ

        if(dist[next_x][next_y] > dist[x][y] + 1) break;
        if(dist[next_x][next_y] <= dist[x][y]){
          if(dist[next_x][next_y] != -1){
            break;
          }
        }

        // まだ見ていない頂点なら push
        if (dist[next_x][next_y] == -1){
            que.push(make_pair(next_x, next_y));
            dist[next_x][next_y] = dist[x][y] + 1; // (next_x, next_y) の距離も更新
        }
      }
    }
  }
  /*
  rep(i,H){
    rep(j,W){
      cout << dist[i][j] << " ";
    }
    cout << endl;
  }
  */
  cout << dist[gx][gy] << endl;
}


Measured memory_bytes: 16080