//
//  main.cpp
//

#include <algorithm>
#include <array>
#include <assert.h>
#include <complex>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = int64_t;
using ull = uint64_t;

[[maybe_unused]] constexpr ll LL_MAX = numeric_limits<ll>::max();
[[maybe_unused]] constexpr ll LL_MIN = numeric_limits<ll>::min();
[[maybe_unused]] constexpr ull ULL_MAX = numeric_limits<ull>::max();

#define rep(i, a, b) for (ll i = (a); i < (b); i++)
#define rrep(i, a, b) for (ll i = (a)-1; i >= (b); i--)

template <typename T>
void chmin(T& x, T y) {
    x = min(x, y);
}

template <typename T>
void chmax(T& x, T y) {
    x = max(x, y);
}

ll csum(ll x, ll y) {
    if (x > 0 && y > 0 && x > LL_MAX - y) {
        return LL_MAX;
    }
    if (x < 0 && y < 0 && x < LL_MIN - y) {
        return LL_MIN;
    }
    return x + y;
}

template<typename T>
vector<T> make_vec_nd(T init, ll size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, ll size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

int main() {
    struct P {
        ll x;
        ll y;
    };
    ll H, W, K;
    cin >> H >> W >> K;
    ll x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    x1--;
    y1--;
    x2--;
    y2--;
    swap(x1, y1);
    swap(x2, y2);
    P start = {x1, y1};
    P goal = {x2, y2};
    auto input = make_vec_nd('.', W, H);
    rep(y,0,H) {
        rep(x,0,W) {
            cin >> input[x][y];
        }
    }
    auto is_wall = [&input](P pos){
        return input[pos.x][pos.y] == '@';
    };
    vector<set<ll>> not_visited_x(H);
    vector<set<ll>> not_visited_y(W);
    vector<set<ll>> not_visited_x_rev(H);
    vector<set<ll>> not_visited_y_rev(W);
    rep(y,0,H) {
        rep(x,0,W) {
            not_visited_x[y].insert(x);
            not_visited_x_rev[y].insert(-x);
        }
    }
    rep(x,0,W) {
        rep(y,0,H) {
            not_visited_y[x].insert(y);
            not_visited_y_rev[x].insert(-y);
        }
    }
    auto visit = [&not_visited_x, &not_visited_y, &not_visited_x_rev, &not_visited_y_rev](P pos){
        not_visited_x[pos.y].erase(pos.x);
        not_visited_x_rev[pos.y].erase(-pos.x);
        not_visited_y[pos.x].erase(pos.y);
        not_visited_y_rev[pos.x].erase(-pos.y);
    };
    auto dist = make_vec_nd(LL_MAX, W, H);
    visit(start);
    dist[start.x][start.y] = 0;
    queue<P> seeds;
    seeds.push(start);
    while (seeds.size() > 0) {
        P seed = seeds.front();
        seeds.pop();
        vector<P> visited;
        rep(dir,0,2) {
            rep(i,0,2) {
                set<ll>* not_visited = nullptr;
                ll line = 0;
                ll seed_pos = 0;
                if (dir == 0) {
                    if (i == 0) {
                        not_visited = &not_visited_x[seed.y];
                    } else {
                        not_visited = &not_visited_x_rev[seed.y];
                    }
                    line = seed.y;
                    seed_pos = seed.x;
                    if (i == 1) {
                        seed_pos *= -1;
                    }
                } else {
                    if (i == 0) {
                        not_visited = &not_visited_y[seed.x];
                    } else {
                        not_visited = &not_visited_y_rev[seed.x];
                    }
                    line = seed.x;
                    seed_pos = seed.y;
                    if (i == 1) {
                        seed_pos *= -1;
                    }
                }
                auto it = not_visited->upper_bound(seed_pos);
                while (true) {
                    if (it == not_visited->end()) {
                        break;
                    }
                    P pos;
                    if (dir == 0) {
                        if (i == 0) {
                            pos = {*it, line};
                        } else {
                            pos = {-(*it), line};
                        }
                    } else {
                        if (i == 0) {
                            pos = {line, *it};
                        } else {
                            pos = {line, -(*it)};
                        }
                    }
                    if (is_wall(pos)) {
                        break;
                    }
                    if (abs(*it - seed_pos) > K) {
                        break;
                    }
                    dist[pos.x][pos.y] = dist[seed.x][seed.y] + 1;
                    visited.push_back(pos);
                    it = next(it);
                }
            }
        }
        for (P pos : visited) {
            seeds.push(pos);
            visit(pos);
        }
    }
    ll ans = dist[goal.x][goal.y];
    if (ans == LL_MAX) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }
}


Measured memory_bytes: 346584