#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <map>
#include <set>
#include <vector>
#include <list>
#include <queue>
#include <sstream>
#include <cmath>
#include <functional>
#include <climits>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define reps(s,i,n) for(int i=s;i<n;i++)
#define rev(i,n) for(int i=n-1;i>=0;i--)
#define skip(i,n,p) for(int i=0;i<n;i+=p)
#define all(a)  (a).begin(),(a).end()
#define int64 long long
#define debug cerr << __FILE__ << ":" << __LINE__ << endl;
#define INF 2147483647

struct Init {
    Init() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout.precision(20);
        cout << fixed;
        // setw(6) << setfill('0')
    }
} init;

template <typename _Ty>
ostream& operator << (ostream& ostr, const vector<_Ty>& v) {
    for(int i = 0; i < (int) v.size(); i++) {
        ostr << v[i] << (i + 1 != v.size() ? " " : "");
    }
    return ostr;
}

template <typename _K, typename _V>
ostream& operator << (ostream& ostr, const map<_K, _V>& v) {
    ostr << "{";
    for (auto iter = v.begin(); iter != v.end(); ++iter) {
        ostr << (*iter).first << ": " << (*iter).second << ", ";
    }
    ostr << "}";
    return ostr;
}

template <typename _K>
ostream& operator << (ostream& ostr, const set<_K>& v) {
    for (auto iter = v.begin(); iter != v.end(); ++iter) {
        ostr << *iter << (iter != v.end() ? " " : "");
    }
    return ostr;
}

template <typename _K, typename _V>
ostream& operator << (ostream& ostr, const pair<_K, _V>& v) {
    ostr << "(" << v.first << ", " << v.second << ")";
    return ostr;
}

vector<string> split(const string &s, char delim) {
    vector<string> result;
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        if (!item.empty()) {
            result.push_back(item);
        }
    }
    return result;
}

template <typename T>
class SegmentTree {
private:
    int n;
    vector<T> data;
    function<T(T, T)> operation;
    function<T(T, T)> change;
    T init_value;
public:
    SegmentTree(vector<T> d, function<T(T, T)> _operation, function<T(T, T)> _change, T _init_value)
        : operation(_operation), change(_change), init_value(_init_value) {
        n = 1;
        while (n < d.size()) n *= 2;
        data.resize(n * 2 - 1, init_value);

        rep(i, d.size()) data[data.size() - n + i] = d[i];
        rev(i, data.size() - n) data[i] = operation(data[i*2+1], data[i*2+2]);
    }

    void update(int index, T val) {
        index += n - 1;
        data[index] = change(data[index], val);
        while (index != 0) {
            index = (index - 1) / 2;
            data[index] = operation(data[index*2+1], data[index*2+2]);
        }
    }

    T query(int a, int b, int k=0, int l=0, int r=-1) {
        if (r < 0) r = n;
        if (r <= a || b <= l) return init_value;
        if (a <= l && r <= b) return data[k];

        T left = query(a, b, k*2+1, l, (l+r)/2);
        T right = query(a, b, k*2+2, (l+r)/2, r);

        return operation(left, right);
    }

    T operator[](int index) {
        return data[index + n - 1];
    }
};

int main() {
    int H, W, K; cin >> H >> W >> K;
    int s1, s2, e1, e2; cin >> s1 >> s2 >> e1 >> e2;
    vector<string> s(H); rep(i, H) cin >> s[i];

    queue<pair<int, int>> que;
    que.push(make_pair(s1-1, s2-1));

    vector<vector<int>> score(H, vector<int>(W, INF));
    score[s1-1][s2-1] = 0;

    while(!que.empty()) {
        auto p = que.front();
        que.pop();

        reps(1, i, K+1) {
            if (p.first + i < H) {
                if (s[p.first + i][p.second] == '@') break;
                if (score[p.first + i][p.second] < score[p.first][p.second]) break;
                if (score[p.first + i][p.second] != INF) continue;
                que.push(make_pair(p.first + i, p.second));
                score[p.first + i][p.second] = score[p.first][p.second] + 1;
            } else {
                break;
            }
        }

        reps(1, i, K+1) {
            if (p.first - i >= 0) {
                if (s[p.first - i][p.second] == '@') break;
                if (score[p.first - i][p.second] < score[p.first][p.second]) break;
                if (score[p.first - i][p.second] != INF) continue;
                que.push(make_pair(p.first - i, p.second));
                score[p.first - i][p.second] = score[p.first][p.second] + 1;
            } else {
                break;
            }
        }

        reps(1, i, K+1) {
            if (p.second - i >= 0) {
                if (s[p.first][p.second - i] == '@') break;
                if (score[p.first][p.second - i] < score[p.first][p.second]) break;
                if (score[p.first][p.second - i] != INF) continue;
                que.push(make_pair(p.first, p.second - i));
                score[p.first][p.second - i] = score[p.first][p.second] + 1;
            } else {
                break;
            }
        }

        reps(1, i, K+1) {
            if (p.second + i < W) {
                if (s[p.first][p.second + i] == '@') break;
                if (score[p.first][p.second + i] < score[p.first][p.second]) break;
                if (score[p.first][p.second + i] != INF) continue;
                que.push(make_pair(p.first, p.second + i));
                score[p.first][p.second + i] = score[p.first][p.second] + 1;
            } else {
                break;
            }
        }
    }

    // cout << endl;
    // for (auto v : score) cout << v << endl;

    int ans = score[e1-1][e2-1];
    if (ans == INF) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }
}


Measured memory_bytes: 12168