#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace std;
using namespace __gnu_pbds;

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

#define lsc(x)      scanf("%lld",&x)
#define sc(x)       scanf("%d",&x)
#define lpr(x)      printf("%lld ",(long long)x)
#define pr(x)       printf("%d ",x)
#define n_l         printf("\n")
#define VI          vector<int>
#define VII         vector<long long int>
#define m_p         make_pair
#define pb          push_back
#define fi           first
#define se           second
#define mset(x,y)   memset(x,y,sizeof(x))
#define sz(v)       (int)v.size()
#define all(v)      v.begin(), v.end()
#define fr(i, a, n) for(int i=a;i<=n;i++)
#define FIO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
const int N=(int)1e6+5;
const int mod = 1000000007;
typedef long long ll;
// order_of_key (val): returns the no. of values strictly less than val
// find_by_order (k): returns the kth largest element iterator.(0-based)
// vector<int>::iterator itr=lower_bound(v.begin(),v.end(),x);
// s.substr(pos[0-indexed], len(default=till end))
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

ll fmod(ll x){if (x<mod) return x;return x%mod;}
ll mul(ll a, ll b, ll c){
    ll ret=0;while(b){if (b%2) ret=(ret+a)%c;a=(a*2)%c;b>>=1;}
    return ret;
}
int modpow(ll a, ll b){
    ll ret=1;while(b){if (b%2) ret=(ret*a)%mod;a=(a*a)%mod;b>>=1;}
    return (int)ret;
}
inline int inv(int x){ return modpow(x, mod-2);}
int isprime[N];
void calc_prime(){
    isprime[1]=1;for(ll i=2;i<N;i++) if (!isprime[i]) for(ll j=i*i;j<N;j+=i) isprime[j]=1;
}
int h, w, k;
vector<VI> area, dis, vis;
queue<pair<int, int> >s;
int X[4] = {0, 0, 1, -1};
int Y[4] = {1, -1, 0, 0};
int main(){
    FIO;
    cin>>h>>w>>k;
    VI tmp(w+1, 0);
    area.pb(tmp);
    VI tmp1(w+1, mod);
    int x1, y1, x2, y2;
    cin>>x1>>y1>>x2>>y2;
    fr(i, 1, h+1){
        dis.pb(tmp1);
        vis.pb(tmp);
    }
    fr(i,1,h){
        string s;cin>>s;
        int cnt = 1;
        for (auto c: s) {
            if (c == '.') tmp[cnt] = 1;
            else tmp[cnt]=0;
            cnt++;
        }
        area.pb(tmp);
    }
    dis[x1][y1] = 0;
    s.push({x1, y1});
    while(s.size()){
        auto pp = s.front();
        s.pop();
        //if(vis[pp.fi][pp.se]) continue;
        //vis[pp.fi][pp.se]=1;
        // trace(pp.fi, pp.se);
        // s.erase(pp);
        fr(i, 0, 3){
            fr(j, 1, k){
                int resx = pp.fi + X[i]*j;
                int resy = pp.se + Y[i]*j;
                // trace(resx, resy);
                if (resx<1 or resx > h or resy<1 or resy>w) break;
                if (!area[resx][resy]) break;
                if (dis[resx][resy] == mod){
                    dis[resx][resy] = dis[pp.fi][pp.se]+1;
                    s.push({resx, resy});
                }
                else if (dis[resx][resy] == dis[pp.fi][pp.se]+1){
                    continue;
                }
                else
                    break;
            }
        }
    }
    cout<<(dis[x2][y2] == mod ? -1: dis[x2][y2])<<'\n';

    return 0;
}


Measured memory_bytes: 35576