#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include"bits/stdc++.h"
#include<unordered_set>
#include<unordered_map>
#include<random>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
int dx[4]={ 1,0,-1,0 };
int dy[4]={ 0,1,0,-1 };

template<typename T>
struct SegmentTree{
private:
    int N;
    vector<T> node;
    function<T(T, T)> F;
    T DEFAULT;
public:
    void init(int n, function<T(T, T)> f, T def){
        F = f;
        DEFAULT = def;
        N = 1;
        while(N < n) N = (N<<1);
        node.assign(2*N-1, DEFAULT);
    }
    T& operator [](int a){
        return node[a+N-1];
    }
    void update(int a, T x){
        a += N-1;
        node[a] = x;
        while(a > 0){
            a = (a-1)>>1;
            node[a] = F(node[(a<<1)+1], node[(a<<1)+2]);
        }
    }
    T query(int a, int b, int k=0, int l=0, int r=-1){
        if(r == -1) r = N;
        if(b <= l || r <= a) return DEFAULT;
        if(a <= l && r <= b) return node[k];
        return F(query(a, b, (k<<1)+1, l, (l+r)>>1), query(a, b, (k<<1)+2, (l+r)>>1, r));
    }
    T m;
    int findL(int a, int b, int k=0, int l=0, int r=-1){
        if(r == -1){
            m = query(a, b);
            r = N;
        }
        if(r <= a || b <= l) return 1e9;
        if(r-l == 1){
            if(node[k] == m) return l;
            else return 1e9;
        }
        if(a <= l && r <= b){
            int valueL = query(a, b, (k<<1)+1, l, (l+r)/2);
            if(valueL == m) return findL(a, b, (k<<1)+1, l, (l+r)>>1);
            int valueR = query(a, b, (k<<1)+2, (l+r)/2, r);
            if(valueR == m) return findL(a, b, (k<<1)+2, (l+r)>>1, r);
            return 1e9;
        }
        return std::min(findL(a, b, (k<<1)+1, l, (l+r)>>1), findL(a, b, (k<<1)+2, (l+r)>>1, r));
    }
    int findR(int a, int b, int k=0, int l=0, int r=-1){
        if(r == -1){
            m = query(a, b);
            r = N;
        }
        if(r <= a || b <= l) return -1e9;
        if(r-l == 1){
            if(node[k] == m) return l;
            else return -1e9;
        }
        if(a <= l && r <= b){
            int valueR = query(a, b, (k<<1)+2, (l+r)/2, r);
            if(valueR == m) return findR(a, b, (k<<1)+2, (l+r)>>1, r);
            int valueL = query(a, b, (k<<1)+1, l, (l+r)/2);
            if(valueL == m) return findR(a, b, (k<<1)+1, l, (l+r)>>1);
            return -1e9;
        }
        return std::max(findR(a, b, (k<<1)+1, l, (l+r)>>1), findR(a, b, (k<<1)+2, (l+r)>>1, r));
    }
};

int H, W, K;
int sy, sx, gy, gx;

vector<vector<bool>> C;
queue<pair<int, int>> que;
vector<vector<int>> cost;
vector<SegmentTree<int>> tate, yoko;

signed main(){
    cin >> H >> W >> K;
    cin >> sy >> sx >> gy >> gx;
    sy--; sx--; gy--; gx--;
    C.resize(H);
    cost.resize(H);
    rep(i, H){
        C[i].resize(W);
        cost[i].assign(W, -1);
        rep(j, W){
            char c;
            cin >> c;
            if(c == '.') C[i][j] = false;
            else C[i][j] = true;
        }
    }

    tate.resize(W);
    rep(i, W) tate[i].init(H, [](int a, int b){ return min(a, b); }, 0);
    yoko.resize(H);
    rep(i, H) yoko[i].init(W, [](int a, int b){ return min(a, b); }, 0);

    que.push({ sy,sx });
    cost[sy][sx] = 0;
    tate[sx].update(sy, 1);
    yoko[sy].update(sx, 1);
    while(!que.empty()){
        int y = que.front().first;
        int x = que.front().second;
        int c = cost[y][x];
        que.pop();
        
        int k = y;
        while(true){
            k = tate[x].findL(k, H);
            if(abs(k-y) > K) break;
            if(tate[x].query(k, k+1) == 1) break;
            if(C[k][x]) break;
            cost[k][x] = c+1;
            que.push({ k,x });
            tate[x].update(k, 1);
            yoko[k].update(x, 1);
        }

        k = y;
        while(true){
            k = tate[x].findR(0, k+1);
            if(abs(k-y) > K) break;
            if(tate[x].query(k, k+1) == 1) break;
            if(C[k][x]) break;
            cost[k][x] = c+1;
            que.push({ k,x });
            tate[x].update(k, 1);
            yoko[k].update(x, 1);
        }

        k = x;
        while(true){
            k = yoko[y].findL(k, W);
            if(abs(k-x) > K) break;
            if(yoko[y].query(k, k+1) == 1) break;
            if(C[y][k]) break;
            cost[y][k] = c+1;
            que.push({ y,k });
            yoko[y].update(k, 1);
            tate[k].update(y, 1);
        }

        k = x;
        while(true){
            k = yoko[y].findR(0, k+1);
            if(abs(k-x) > K) break;
            if(yoko[y].query(k, k+1) == 1) break;
            if(C[y][k]) break;
            cost[y][k] = c+1;
            que.push({ y,k });
            yoko[y].update(k, 1);
            tate[k].update(y, 1);
        }
    }
    /*rep(i, H){
        rep(j, W){
            cout << cost[i][j] << " ";
        }
        cout << endl;
    }*/
    cout << cost[gy][gx] << endl;
}

/*
3 5 2
3 2 3 4
.....
.@..@
..@..

5 3 2
2 3 4 3
...
.@.
..@
...
.@.
*/

Measured memory_bytes: 117092