#include <bits/stdc++.h>

#define         endl     "\n"
#define          EPS     1E-9
#define           PI     acos(-1)
#define        sq(x)     ((x)*(x))
#define           ln     length
#define            F     first
#define            S     second
#define           MP     make_pair
#define           MT     make_tuple
#define           PB     push_back
#define           PF     push_front
#define          PPB     pop_back
#define          PPF     pop_front
#define       ODD(x)     (((x)&1LL) ? (1):(0))
#define       all(v)     (v).begin(), (v).end()
#define    UNIQUE(v)     (v).erase(unique(all(v)), (v).end())
#define     f0(i, n)     for (i = (0); i <  (n); ++i)
#define     f1(i, n)     for (i = (1); i <= (n); ++i)
#define fab(i, a, b)     for (i = (a); i <= (b); ++i)
#define  fr(i, b, a)     for (i = (b); i >= (a); --i)
#define      mark(x)     (marked[(x)>>6] |= (1L<<(((x)%64)>>1)))
#define        on(x)     (marked[(x)>>6] &  (1L<<(((x)%64)>>1)))

using namespace std;

/*
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,
	tree_order_statistics_node_update> indexed_set;
//*/
typedef long long int     ll;
#define int               long int
typedef vector<ll>        vll;
typedef pair<ll, ll>      pll;
//typedef tuple<ll, ll, ll> tll

template <typename T> inline bool compare(T x, T y) { return x > y; }
template <typename T> T binaryExpo(T n, T p)        { if (p == 0) { return 1LL;   } if (p&1) { return  n*binaryExpo(n, p - 1);     } T ret = binaryExpo(n, p/2) ; return ret * ret;     }
template <typename T> T bigMod(T n, T p, T m)       { if (p == 0) { return 1LL%m; } if (p&1) { return (n%m*bigMod(n, p - 1, m))%m; } T ret = bigMod(n, p/2, m)%m; return (ret * ret)%m; }
template <typename T> T modInv(T n, T m)            { return bigMod(n, m - 2, m); }

const ll maxN = 1e6+10;   const ll maxB =    320; const ll  INF =  9187201950435737471; //const int  INF =  2139062143;
const ll maxA = 1e6+10;   const ll MOD  = 1e9+7 ; const ll _INF = -9187201950435737472; //const int _INF = -2139062144;

//int dx[8] = { 0,   1,  1,  1,  0,  -1, -1, -1};
//int dy[8] = {-1,  -1,  0,  1,  1,   1,  0, -1};
//              N   NE   E  SE   S   SW   W   NW
  int dx[4] = { 0,       1,      0,      -1    };
  int dy[4] = {-1,       0,      1,       0    };
  int row, column;

int marked[//(maxA>>6) // only for odd numbers
    +2];
vector<ll>prime;

//* function prototypes
void sieve(ll n);
bool is_prime(ll num);
//*/

#ifdef DEBUG
#endif // DEBUG
#ifndef ONLINE_JUDGE
//#define ONLINE_JUDGE
#endif // ONLINE_JUDGE
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map<ll, string>res = {{0, "No"}, {1, "Yes"}};
string grid[maxN+10];
ll dis[4][maxN+10];
ll processed[4][maxN/64+2];

string ll2s(ll n)
{
    if (n == -1) return "@";
    string ret;
    if (n == INF) return "?";
    else if (n == 0) ret = "0";
    while (n%10)
    {
        ret.PB('0'+n%10); n /= 10;
    }
    reverse(all(ret));
    return ret;
}
ll min_dis(ll y, ll x)
{
    ll ret = INF, i;
    if (grid[y][x] == '@') return -1;
    f0(i, 4) ret = min(ret, (ll)dis[i][y*column+x]);
    return ret;
}
ll dis_(ll dr, ll y, ll x)
{
    if (grid[y][x] == '@') return -1;
    return dis[dr][column*y+x];
}
void print()
{
    ll i, j;
    #define SW 3
    //cerr << "   ";
    //f0(i, column) cerr << "_______"; cerr << endl;
    cerr << "   ";
    f0(i, column) cerr << "|" << setw(SW*2)  << i << setw(SW*2) << ""; cerr << "|\n   ";
    f0(i, column) cerr << "|____________" ; cerr << "|\n";
    f0(j, row)
    {
        cerr << setw(3) << "";
        f0(i, column) cerr << "|" << setw(SW*4)  << ""; cerr << "|" << "\n";
        cerr << setw(3) << "";
        f0(i, column) cerr << "|" << setw(SW*2)  << ll2s(dis_(0, j, i)) << setw(SW*2) << ""; cerr << "|\n";
        cerr << left << setw(3) << j << right;
        f0(i, column) cerr << "|" << setw(SW)  << ll2s(dis_(3, j, i)) << setw(SW) << ""<< setw(SW)  << ll2s(dis_(1, j, i)) << setw(SW) << ""; cerr << "|" << setw(3) << j << "\n   ";
        //cerr << setw(3) << "";
        f0(i, column) cerr << "|" << setw(SW*2)  << ll2s(dis_(2, j, i)) << setw(SW*2) << ""; cerr << "|\n   ";
        f0(i, column)
        {
            if (grid[j][i] == '@') cerr << "|____________" ;
            else cerr << "|____________" ;
        } cerr << "|\n";
    }
    cerr << "   ";
    f0(i, column) cerr << "|" << setw(SW*2)  << i << setw(SW*2) << ""; cerr << "|\n";
    cerr << "\n\n";
}

signed main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cout.precision(15); cout << fixed;
#ifndef ONLINE_JUDGE
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE

    //sieve(maxA);
    ll number_of_test_case = 1, test_case;
    //cin >> number_of_test_case;
    for (test_case = 1; test_case <= number_of_test_case; test_case++)
    {
    	//cout << "Test #" << test_case << ": ";
    	//cout << "Case "  << test_case << ": ";
    	ll i, j, k, m, n, query_type; ll a, b, x, y;
        ll x_1, x_2, y_1, y_2;

    	cin >> row >> column >> k >> y_1 >> x_1 >> y_2 >> x_2;
    	y_1--; x_1--; y_2--; x_2--;
    	f0(i, row) cin >> grid[i];

#ifndef ONLINE_JUDGE
    	cerr << row << " " << column << " " << k << "\n"
            << y_1 << " " << x_1 << " " << y_2 << " " << x_2 << endl;
        f0(i, row) cerr << grid[i] << endl;
#endif // ONLINE_JUDGE

    	memset(dis, 127, sizeof dis);
    	deque<tuple<ll, ll, ll, ll>>q;
    	q.PB(MT(y_1, x_1, 0, k)); q.PB(MT(y_1, x_1, 2, k));
    	f0(i, 4) dis[i][y_1*column+x_1] = 0;

#ifndef ONLINE_JUDGE
        print();
#endif // ONLINE_JUDGE
        ll count_ = 0;
    	while (not q.empty())
        {
            bool flag = 0;
            ll y, x, dr, cnt;
            tie(y, x, dr, cnt) = q.front(); q.pop_front();

#ifndef ONLINE_JUDGE
            cerr << "SI     : " << ++count_ << endl;
            cerr << "(x, y) : (" << x << ", " << y << ")\n";
            cerr << "dr     : " << dr << endl;
            cerr << "cnt    : " << cnt << endl;
            cerr << "dis    : " << dis[dr][y*column+x] << endl;
            cerr << "min dis: " << min_dis(y, x) << "\n";
#endif // ONLINE_JUDGE

#define  _mark(d, y, x) (processed[d][(column*y+x)/64] |= (1LL<<((column*y+x)%64)))
#define    _on(d, y, x) (processed[d][(column*y+x)/64] &  (1LL<<((column*y+x)%64)))
            if (_on(dr, y, x)) continue;
            else
            {
                _mark(dr, y, x);
            }

#define valid(y, x) (y >= 0 and y < row and x >= 0 and x < column and grid[y][x] == '.')
            ll ny, nx, ndr, ncnt, ndis;

            ndr = dr;
            ny = y+dy[ndr]; nx = x+dx[ndr];
#ifndef ONLINE_JUDGE
            cerr << "(" << nx << ", " << ny << ")\n";
#endif // ONLINE_JUDGE
            if (valid(ny, nx) and cnt < k and dis[dr][column*y+x] < dis[ndr][column*ny+nx])
            {
#ifndef ONLINE_JUDGE
                cerr << "going front at cost 0\n";
                flag = 1;
#endif // ONLINE_JUDGE
                dis[ndr][column*ny+nx] = dis[dr][column*y+x];
                q.PF(MT(ny, nx, ndr, cnt+1));
            }
            else if (valid(ny, nx) and dis[dr][column*y+x]+1 < dis[ndr][column*ny+nx])
            {
#ifndef ONLINE_JUDGE
                cerr << "going front at cost 1\n";
                flag = 1;
#endif // ONLINE_JUDGE
                dis[ndr][column*ny+nx] = dis[dr][column*y+x]+1;
                q.PB(MT(ny, nx, ndr, 1));
            }

            ndr = dr-1; if (ndr < 0) ndr += 4;
            ny = y+dy[ndr]; nx = x+dx[ndr];
#ifndef ONLINE_JUDGE
            cerr << "(" << nx << ", " << ny << ")\n";
#endif // ONLINE_JUDGE
            if (valid(ny, nx) and dis[dr][column*y+x]+1 < dis[ndr][column*ny+nx])
            {
#ifndef ONLINE_JUDGE
                cerr << "going left\n";
                flag = 1;
#endif // ONLINE_JUDGE
                dis[ndr][column*ny+nx] = dis[dr][column*y+x]+1;
                q.PB(MT(ny, nx, ndr, 1));
            }

            ndr = dr+1; if (ndr >= 4) ndr -= 4;
            ny = y+dy[ndr]; nx = x+dx[ndr];
#ifndef ONLINE_JUDGE
            cerr << "(" << nx << ", " << ny << ")\n";
#endif // ONLINE_JUDGE
            if (valid(ny, nx) and dis[dr][column*y+x]+1 < dis[ndr][column*ny+nx])
            {
#ifndef ONLINE_JUDGE
                cerr << "going right\n";
                flag = 1;
#endif // ONLINE_JUDGE
                dis[ndr][column*ny+nx] = dis[dr][column*y+x]+1;
                q.PB(MT(ny, nx, ndr, 1));
            }
#ifndef ONLINE_JUDGE
            if (flag) print();
#endif // ONLINE_JUDGE
        }
#ifndef ONLINE_JUDGE
            print();
#endif // ONLINE_JUDGE

        ll ans = INF;
        f0(i, 4) ans = min(ans, dis[i][column*y_2+x_2]);
        if (ans == INF) ans = -1;

        cout << ans << endl;
    }

#ifndef ONLINE_JUDGE
    cerr << "\n........................   execution time : " << 1.0*clock()/CLOCKS_PER_SEC << " s";
#endif // ONLINE_JUDGE
    return 0;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~









bool is_prime(ll num) { return (num > 1 && (num == 2 || (ODD(num) && !on(num))) ); }
void sieve(ll n)
{
    ll i, j; mark(1);
    for (i = 3; i*i <= n; i += 2) { if (!on(i)) { for (j = i*i; j <= n; j += i+i) mark(j); } }
    prime.clear(); prime.push_back(2);
    for (i = 3; i <= n; i += 2) { if (is_prime(i)) prime.push_back(i); }
}



Measured memory_bytes: 72212