Problem:
Score : 600 points

Problem Statement

Snuke, a water strider, lives in a rectangular pond that can be seen as a grid with H east-west rows and W north-south columns. Let (i,j) be the square at the i-th row from the north and j-th column from the west.

Some of the squares have a lotus leaf on it and cannot be entered.
The square (i,j) has a lotus leaf on it if c_{ij} is @, and it does not if c_{ij} is ..

In one stroke, Snuke can move between 1 and K squares (inclusive) toward one of the four directions: north, east, south, and west.
The move may not pass through a square with a lotus leaf. Moving to such a square or out of the pond is also forbidden.

Find the minimum number of strokes Snuke takes to travel from the square (x_1,y_1) to (x_2,y_2).
If the travel from (x_1,y_1) to (x_2,y_2) is impossible, point out that fact.

Constraints

1 \leq H,W,K \leq 10^6

H \times W \leq 10^6

1 \leq x_1,x_2 \leq H

1 \leq y_1,y_2 \leq W

x_1 \neq x_2 or y_1 \neq y_2.

c_{i,j} is . or @.

c_{x_1,y_1} = .

c_{x_2,y_2} = .

All numbers in input are integers.

Input

Input is given from Standard Input in the following format:

H W K
x_1 y_1 x_2 y_2
c_{1,1}c_{1,2} .. c_{1,W}
c_{2,1}c_{2,2} .. c_{2,W}
:
c_{H,1}c_{H,2} .. c_{H,W}

Output

Print the minimum number of strokes Snuke takes to travel from the square (x_1,y_1) to (x_2,y_2), or print -1 if the travel is impossible.

Sample Input 1

3 5 2
3 2 3 4
.....
.@..@
..@..

Sample Output 1

5

Initially, Snuke is at the square (3,2).
He can reach the square (3, 4) by making five strokes as follows:

From (3, 2), go west one square to (3, 1).

From (3, 1), go north two squares to (1, 1).

From (1, 1), go east two squares to (1, 3).

From (1, 3), go east one square to (1, 4).

From (1, 4), go south two squares to (3, 4).

Sample Input 2

1 6 4
1 1 1 6
......

Sample Output 2

2

Sample Input 3

3 3 1
2 1 2 3
.@.
.@.
.@.

Sample Output 3

-1

Solution in C++ (GCC 9.2.1) (judge verdict: Time Limit Exceeded)


// Problem : F - Pond Skater
// Contest : AtCoder - AtCoder Beginner Contest 170
// URL : https://atcoder.jp/contests/abc170/tasks/abc170_f
// Memory Limit : 1024 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include<bits/stdc++.h>
using namespace std;
#define flush  cin.ignore(numeric_limits<streamsize>::max(),'\n')
#define fill(w,t) memset(w,t,sizeof(w))
#define google cout<<"Case #"<<countu<<": "
#define S(t) (ll)t.size()
#define bl '\n'
#define nl cout<<bl
#define cout1(a) cout<<a<<bl
#define cout2(a,b) cout<<a<<" "<<b<<bl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<bl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<bl
#define print(a,s,e) for(ll i=s;i<=e;i++){ cout<<a[i]<<" "; }
#define rprint(a,s,e) for(ll i=s;i>=e;i--){ cout<<a[i]<<" "; }
#define input(a,s,e) sfor(p,s,e) cin>>a[p]
#define all(v) v.begin(),v.end()
#define ll long long
#define ldb long double
#define db double
#define ull unsigned long long
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define mk make_pair
#define pll pair<ll,ll>
#define pldb pair<ldb,ldb>
#define fi first
#define se second
#define vull vector<ull>
#define vll vector<ll>
#define vldb vector<ldb>
#define vpll vector< pll >
#define vpldb vector< pldb >
#define pqmin priority_queue<ll,vector<ll>,greater<ll> >     //minheap
#define pq priority_queue<ll>                                //maxheap ll
#define pqpll priority_queue<pll>                            //maxheap pll
#define pqpllmin priority_queue<pll, vector<pll>, greater<pll> >   //minheap pll
#define mll map<ll,ll>
#define mldb map<ldb,ldb>
#define umll unordered_map<ll,ll>
#define sll set<ll>
#define usll unordered_set<ll>
#define sfor(i,a,b) for (ll i = (a); i <= (b); ++i)
#define rfor(i,b,a) for (ll i = (b); i >= (a); --i)
const ll mod = 1e9+7;
const ll maxn = 1e6+1;
const ll llmax = (1ll<<60);
const int intmax = (1<<30);
const ldb PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899863;
ll *fact , *ifact;
vll primes;
ll *spf; 
void sieve() 
{
    spf = new ll[maxn+1];
    fill(spf,0);
	spf[0]=0; spf[1]=1;
    for(ll i =2; i<=maxn; i++)
    {
        if(spf[i])
         continue;
        spf[i]=i;
        for(ll j = i*i; j<=maxn; j+=i)
        {
        	if(spf[j]==0)
         	    spf[j]=i;
    	}
    }
    for (ll p=2; p<=maxn; p++)
      if (spf[p]==p)
          primes.pb(p);
}
vll primes1;
void sieve2(ll l,ll r)
{
	bool isprime[r-l+1];
	fill(isprime,1);
	if(l==1)
	    isprime[0]=false;
	ll base;
	for(ll i=0;primes[i]*primes[i]<=r;i++)
	{
		base = (l/primes[i])*primes[i];
		if(base<l)
		{
			base += primes[i];
		}
		for(long long j=base;j<=r;j+=primes[i])
		{
			isprime[j-l]=false;
		}
		if(base==primes[i]){
			isprime[base-l]=true;
		}
	}
	for(int i=0;i<r-l+1;i++)
	{
		if(isprime[i])
		    primes1.pb(i+l);
	}
}
// void primefactorization(ll x,mll &mp)
// {
//      for(ll i=0;primes[i]*primes[i]<=x;i++)
//     {
//         while(x%primes[i]==0)
//         {
//             mp[primes[i]]++;
//             x/=primes[i];
//         }
//     }
//     if(x!=1)
//     {
//         mp[x]++;
//     }
// }
void primefactorization(ll n,mll &mp)
{
    while(n!=1)
    {
        mp[spf[n]]++;
        n/=spf[n];
    }
}

bool primeornot(ll n)
{
    for(ll i=0;primes[i]*primes[i]<=n;i++)
    {
        if(n%primes[i]==0)
        {
            return false;
        }
    }
    return true;
}

void allfactors(vll &v,ll n)
{
    for(ll i=1;i*i<=n;i++)
	{
        if(n%i==0)
        {
            v.pb(i);
            if(i*i!=n)
            {
                v.pb(n/i);
            }
        }
	}
	sort(v.begin(),v.end());
}

ll power(ll a,ll n)
{
 ll res=1;
 while(n)
{
 if(n%2){
    res=( (res%mod) * (a%mod)) % mod;
 }
    a=( (a%mod) * (a%mod) ) % mod;
    n/=2;
}
res%=mod;
return res;
}

ll modInv(ll a){
	return power(a,mod-2)%mod;
}

void modFact()
{
    ll n = maxn;
    ifact=new ll[n+1];
    fact=new ll[n+1];
    fact[0]=fact[1]=1;
    for(int i=2;i<=n;i++)
    {
        fact[i]=(i*fact[i-1])%mod;
    }
    ifact[n]=modInv(fact[n]);
    for(int i=n-1;i>=0;i--)
    {
        ifact[i]=((i+1)*ifact[i+1])%mod;
    }
}

ll ncr(ll n, ll r)
{
    if(n<r || r<0)
        return 0;
    ll ans=fact[n];
    ans*=ifact[r];
    ans%=mod;
    ans*=ifact[n-r];
    ans%=mod;
    return ans;
}

ll npr(ll n, ll r)
{
    if(n<r || r<0)
        return 0;
    ll ans=fact[n];
    ans*=ifact[n-r];
    return ans%mod;
}

ll lcm(ll a,ll b)
{
	ll x=__gcd(a,b);
	a/=x;
	b/=x;
	ll sum=a*b*x;
	return sum;
}

bool ispalindrome(string str,ll l,ll r)
{
    while(l<=r)
    {
        if(str[l]!=str[r])
        return false;
        l++;
        r--;
    }
    return true;
}

ll reversenum(ll n)
{
    ll ans=0;
    while(n)
    {
        ans= (ans*10)+n%10;
        n/=10;
    }
    return ans;
}

void fraction(string &str, ll &num,ll &den) 
{
    ll n = str.length();
    ll count_after_dot = 0;
    bool dot_seen = false;
  
    for (ll i = 0; i < n; i++) 
    { 
        if (str[i] != '.') 
        { 
            num = num*10 + (str[i] - '0'); 
            if (dot_seen == true) 
                count_after_dot++; 
        } 
        else
            dot_seen = true; 
    }
    if (dot_seen == false)
    {
        den=1;
        return;
    }
    ll dem = (ll)pow(10, count_after_dot);
    ll g = __gcd(num, dem);
    num=num/g;
    den = dem/g;
    return; 
}

string convert_to_bit(ll a,int bit)
{
	string s;
	while(a>0){
		s+=(a%2)+48;
		a/=2;
	}
	while(s.size()<bit)
		s+='0';
	reverse(s.begin(),s.end());
	return s;
}

string tobinary(ll n) 
{
    if (n==0) return "0";
    else if (n==1) return "1";
    else if (n%2 == 0) return tobinary(n/2) + "0";
    else if (n%2 != 0) return tobinary(n/2) + "1";
}
#define countsetbit  __builtin_popcount

ll countbit(ll n) 
{ 
    return (ll)log2(n)+1; 
}

ll setbit(ll n, ll k) 
{ 
    return (n | (1 << (k - 1))); 
}

ll clearbit(ll n, ll k) 
{ 
    return (n & (~(1 << (k - 1)))); 
}

ll togglebit(ll n, ll k) 
{ 
    return (n ^ (1 << (k - 1))); 
}
//ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
//Use (<<) for multiplication
//Use (>>) for division
//ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);
// find_by_order -> value at index
// order_of_key -> index of value
// while using (1<<i) use ((ll)1<<(ll)i) 
// in Floyd-Warshall Algo, k is outer loop 
// If an element was not initially in map and if asked mp[a],the element gets inserted 
// a%=mod take a lot of time... try to use it minimum and use memset as it reduces a lot of time usage...use if(a>=mod) a%=mod
//cout<<(double) can be harmful , always use printf(%.9llf)...take scanf("%lf",&p[i][j]) as input , not llf;
//use s.erase(it++) for erasing iterator and then moving to the next one
//never use adj.resize(n) as value is persistent, always erase
//use __builtin_popcountll() for ll
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
//always check the use of segment tree using bottom-up dp

// ll h,w;

void solve(ll countu)
{ 
    ll h,w,k;
    cin>>h>>w>>k;
    ll x1,y1,x2,y2;
    cin>>x1>>y1>>x2>>y2;
    x1--;
    y1--;
    x2--;
    y2--;
    vector<string> str;
    str.resize(h);
    sfor(i,0,h-1)
    {
    	cin>>str[i];
    }
    ll ans[h][w];
    fill(ans,-1);
    bool vis[h][w];
    fill(vis,0);
    queue<pll> t;
    vis[x1][y1]=1;
    ans[x1][y1]=0;
    t.push({x1,y1});
    while(S(t))
    {
    	pll p = t.front();
    	t.pop();
    	// ll tx = p.fi,ty=p.se;
    	if(p.fi==x2&&p.se==y2)break;
    	bool f1=1,f2=1,f3=1,f4=1;
    	sfor(i,1,k)
    	{
    		if(p.fi+i<h&&f1)
    		{
    			if(str[p.fi+i][p.se]=='@') f1=false;
    			if(vis[p.fi+i][p.se]==0&&str[p.fi+i][p.se]=='.')
	    		{
	    			ans[p.fi+i][p.se] = ans[p.fi][p.se]+1;
	    			vis[p.fi+i][p.se] = 1;
	    			t.push({p.fi+i,p.se});
	    		}
    		}
    		if(p.fi-i>=0&&f2)
	    	{
	    		if(str[p.fi-i][p.se]=='@') f2=false;
	    		if(vis[p.fi-i][p.se]==0&&str[p.fi-i][p.se]=='.')
	    		{
	    			ans[p.fi-i][p.se] = ans[p.fi][p.se]+1;
	    			vis[p.fi-i][p.se] = 1;
	    			t.push({p.fi-i,p.se});
	    		}
	    	}
	    	if(p.se-i>=0&&f3)
	    	{
	    		if(str[p.fi][p.se-i]=='@') f3=false;
	    		if(vis[p.fi][p.se-i]==0&&str[p.fi][p.se-i]=='.')
	    		{
	    			ans[p.fi][p.se-i] = ans[p.fi][p.se]+1;
	    			vis[p.fi][p.se-i] = 1;
	    			t.push({p.fi,p.se-i});
	    		}
	    	}
	    	if(p.se+i<w&&f4)
	    	{
	    		if(str[p.fi][p.se+i]=='@') f4=false;
	    		if(vis[p.fi][p.se+i]==0&&str[p.fi][p.se+i]=='.')
	    		{
	    			ans[p.fi][p.se+i] = ans[p.fi][p.se]+1;
	    			vis[p.fi][p.se+i] = 1;
	    			t.push({p.fi,p.se+i});
	    		}
	    	}
    	}    	
    }
    cout<<ans[x2][y2];
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    srand(time(0));



    ll t=1;
    // cin>>t;
    sfor(i,1,t)
        solve(i);


    return 0;
}