// #define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; 
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, deque<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

template<typename T> T read() {T x;cin >> x;return x;}
template<typename T> vector<T> read(int n) {vector<T> v(n);for(auto& x : v) cin >> x;return v;}
template<typename A, typename B>istream& operator>>(istream& in, pair<A, B>& p) {return in >> p.first >> p.second;}
template<class... Args> auto createVec(size_t n, Args&&... args) { if constexpr(sizeof...(args) == 1) return vector(n, args...); else return vector(n, create(args...)); }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin); i < (end); i++)
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define all(a) a.begin(), a.end()
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
    #define debug(args...) if(0){}
#else
    #define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); dbg(_it, true, args); }
    void dbg(istream_iterator<string> it, bool isStart) {cerr << "</debug>" << endl;}
    template<typename T, typename... Args>
    void dbg(istream_iterator<string> it, bool isStart, T a, Args... args) {
        if(isStart) cerr << "<debug>" << endl;
        cerr << "  " << *it << " = " << a << endl;
        dbg(++it, false, args...);
    }
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
std::chrono::steady_clock::time_point __clock__;
void startTime() {__clock__ = std::chrono::steady_clock::now();}
ld getTime() {
    auto end = std::chrono::steady_clock::now();
    auto t = std::chrono::duration_cast<std::chrono::microseconds> (end-__clock__).count();
    return ld(t)/1e6;
}
void timeit(string msg) {
    cerr << "> " << msg << ": " << precise(6) << getTime() << endl;
}
template<typename T> inline bool maxi(T& a, T b) { return b > a ? (a = b, true) : false; }
template<typename T> inline bool mini(T& a, T b) { return b < a ? (a = b, true) : false; }
const ld PI = asin(1) * 2;
const ld eps = 1e-6;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 1000000007;
const int MAXN = 200000;

enum Dir {
    UP,
    DOWN,
    LEFT,
    RIGHT
};

Dir rotate(Dir d) {
    if (d == UP) return RIGHT;
    if (d == RIGHT) return DOWN;
    if (d == DOWN) return LEFT;
    return UP;
}

ll roundUp(ll val, ll base) {
    if (val % base == 0) return val;
    ll x = val / base;
    return (x+1) * base;
}

using Node = pair<pii, Dir>;

vector<pair<Node, ll>> getNeighs(Node u, ll dist, ll k) {
    vector<pair<Node, ll>> neighs;
    FOR(d, 0, 4) {
        if (d == u.second) continue;
        neighs.pb({{u.first, (Dir)d}, roundUp(dist, k) - dist});
    }
    auto d = u.second;
    if (d == UP)    neighs.pb({{{u.first.first-1, u.first.second}, d}, 1});
    if (d == DOWN)  neighs.pb({{{u.first.first+1, u.first.second}, d}, 1});
    if (d == LEFT)  neighs.pb({{{u.first.first, u.first.second-1}, d}, 1});
    if (d == RIGHT) neighs.pb({{{u.first.first, u.first.second+1}, d}, 1});
    return neighs;
}

bool isValid(Node u, const vector<vector<char>>& brd) {
    int n = brd.size();
    int m = brd[0].size();
    int i = u.first.first;
    int j = u.first.second;
    return i >= 0 && i < n && j >= 0 && j < m && brd[i][j] == '.';
}

ll& getDist(vector<vector<vector<ll>>>& dists, Node u) {
    return dists[u.first.first][u.first.second][u.second];
}

ll dijkstra(Node start, pii goal, vector<vector<char>>& brd, int k) {
    int n = brd.size();
    int m = brd[0].size();
    min_heap<pair<ll, Node>> Q;
    vector<vector<vector<ll>>> dists(n, vector<vector<ll>>(m, vector<ll>(4, OO)));
    getDist(dists, start) = 0;
    Q.push({0, start});
    while(!Q.empty()) {
        auto t = Q.top(); Q.pop();
        auto u = t.second;
        ll d = t.first;
        if (d > getDist(dists, u)) continue;
        if (u.first == goal) return d;
        auto neighs = getNeighs(u, d, k);
        for(auto neigh : neighs) {
            auto v = neigh.first;
            if (!isValid(v, brd)) continue;
            auto w = neigh.second;
            if (getDist(dists, u) + w < getDist(dists, v)) {
                getDist(dists, v) = getDist(dists, u) + w;
                Q.push({getDist(dists, v), v});
            }
        }
    }
    return -1;
}

int main()
{
    FAST_IO;
    startTime();

    // int n = 1000, m = 1000, k = 1000000;
    // cout << n << " " << m << " " << k << endl;
    // cout << "1 1 " << n << " " << m << endl;
    // FOR(i, 0, n) {
    //     FOR(j, 0, m) {
    //         cout << ".";
    //     }
    //     cout << endl;
    // }

    int h, w, k;
    cin >> h >> w >> k;
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    x1--, y1--, x2--, y2--;

    vector<vector<char>> brd(h, vector<char>(w));
    FOR(i, 0, h) {
        FOR(j, 0, w) {
            cin >> brd[i][j];
        }
    }

    ll ans = dijkstra({{x1, y1}, UP}, {x2, y2}, brd, k);
    if (ans < 0) cout << -1 << endl;
    else cout << roundUp(ans, k) / k << endl;

    timeit("Finished");
    return 0;
}

Measured memory_bytes: 144848