/*

    author : s@if

*/

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define 		NIL 			-1
#define		 	fi	 		    first
#define 		sec 			second
#define 		MAX 			INT_MAX
#define 		ll 			    long long
#define 		PI 			    acos(-1.0)
#define			MOD 			1000000007
#define 		PLL 			pair<ll,ll>
#define 		PII			    pair<int,int>
#define 		ull 			unsigned long long
#define 		For(i,a,b) 		for(int i=a;i<=(int)b;i++)
typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update> new_data_set;

//*find_by_order(k)  gives the kth element;
//order_of_key(item)   gives the index(number of element strictly less than item) of item;


inline int in() {int x; scanf("%d", &x); return x; }
bool Check(int N , int pos)	{	return (bool) (N & (1<<pos));}
int Set(int N, int pos) {	return N = N | (1<<pos);}

int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};    // King's move
int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};
int hx[]={-2,-2,-1,+1,+2,+2,-1,+1};    // Knight's move
int hy[]={+1,-1,+2,+2,-1,+1,-2,-2};
int dx[]={+1,-1,+0,+0};
int dy[]={+0,+0,+1,-1};

const int MAXN = (int)2e5+9;
const int INF = 1e9;

struct node
{
    ll x, y, d; PLL w;
    node(){}
    node(int _x, int _y, int _d, PLL _w)
    {
        x = _x, y = _y, d = _d, w = _w;
    }

    bool operator<(const node &nd)const
    {
        return w.fi*nd.w.sec > w.sec*nd.w.fi;
    }
};

PLL ADD(PLL a, PLL b)
{
    ll gc = __gcd(a.sec,b.sec);
    ll lc = (a.sec*b.sec)/gc;
    PLL ret;
    ret.sec = lc;
    ret.fi = lc/a.sec*a.fi + lc/b.sec*b.fi;

    return ret;
}

vector<string>grid;
vector<vector<vector<PLL> > >dist;

int main()
{
/*	freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);  */

    ll i,j,k,l,m,n,p,q,x,y,u,v,r,tc,t;

    cin>>n>>m>>k;
    ll x1, y1, x2, y2;
    cin>>x1>>y1>>x2>>y2;
    x1--, y1--, x2--, y2--;
    dist.resize(n+9);
    grid.resize(n+9);
    for(i=0; i<n; i++)
    {
        dist[i].resize(m+9);
        for(j=0; j<m; j++){
            dist[i][j].resize(5);
            dist[i][j][0] = PLL(INF,1);
            dist[i][j][1] = PLL(INF,1);
            dist[i][j][2] = PLL(INF,1);
            dist[i][j][3] = PLL(INF,1);
        }
    }

    for(i=0; i<n; i++)
    {
        cin>>grid[i];
    }

    priority_queue<node>pq;
    pq.push(node(x1,y1,0,PLL(0,1)));
    pq.push(node(x1,y1,1,PLL(0,1)));
    pq.push(node(x1,y1,2,PLL(0,1)));
    pq.push(node(x1,y1,3,PLL(0,1)));
    dist[x1][y1][0] = dist[x1][y1][1] = PLL(0,1);
    dist[x1][y1][2] = dist[x1][y1][3] = PLL(0,1);

    while(!pq.empty())
    {
        node ndu = pq.top(); pq.pop();

        for(i=0; i<4; i++)
        {
            x = ndu.x+dx[i];
            y = ndu.y+dy[i];
            if(x>=0 && x<n && y>=0 && y<m && grid[x][y]=='.')
            {
                PLL pw;
                if(ndu.d==i){
                    pw = ADD(ndu.w , PLL(1,k));
                }
                else{
                    pw.fi = ndu.w.fi/ndu.w.sec;
                    if(ndu.w.fi%ndu.w.sec!=0) pw.fi++; pw.sec = 1;
                    pw = ADD(pw, PLL(1,k));
                }

                if(pw.fi*dist[x][y][i].sec < pw.sec*dist[x][y][i].fi){
                    dist[x][y][i] = pw;
                    pq.push(node(x,y,i,pw));
                }
            }
        }
    }

    PLL ans = PLL(INF,1);
    for(i=0; i<4; i++)
    {
        if(dist[x2][y2][i].fi*ans.sec < dist[x2][y2][i].sec*ans.fi)
            ans = dist[x2][y2][i];
    }

    if(ans.fi==INF) cout<<-1<<endl;
    else {
        ll c = ans.fi/ans.sec+(ans.fi%ans.sec!=0);
        cout<<c<<endl;
    }
  //  main();

    return 0;
}

// read the question correctly (is y a vowel? what are the exact constraints?)
// look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)


Measured memory_bytes: 132320