#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define pi 3.141592653589793238
#define int long long
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;


vector<vector<int> >dis;
set<int>s;
vector<vector<int> >col1,row1,col2,row2;
vector<vector<pair<int,int> > >seg_row,seg_col;
string a[1000005];

void build_row(int ver,int tl,int tr,int x)
{
    if(tl>tr)
        return ;
    else if(tl==tr)
    {
        if(a[x][tl]=='.')
            seg_row[x][ver]={1e17,tl};
        else
            seg_row[x][ver]={-1,tl};
    }
    else
    {
        int tm=(tl+tr)/2;
        build_row(2*ver,tl,tm,x);
        build_row(2*ver+1,tm+1,tr,x);
        seg_row[x][ver]=max(seg_row[x][2*ver],seg_row[x][2*ver+1]);
    }    
}

void build_col(int ver,int tl,int tr,int x)
{
    if(tl>tr)
        return ;
    else if(tl==tr)
    {
        if(a[tl][x]=='.')
            seg_col[x][ver]={1e17,tl};
        else
            seg_col[x][ver]={-1,tl};
    }
    else
    {
        int tm=(tl+tr)/2;
        build_col(2*ver,tl,tm,x);
        build_col(2*ver+1,tm+1,tr,x);
        seg_col[x][ver]=max(seg_col[x][2*ver],seg_col[x][2*ver+1]);
    }    
}

void upd_row(int ver,int tl,int tr,int pos,int val,int x)
{
    if(tl>tr)
        return ;
    else if(tl==tr)
    {
        seg_row[x][ver].first=min(seg_row[x][ver].first,val);
    }
    else
    {
        int tm=(tl+tr)/2;
        if(tm>=pos)
            upd_row(2*ver,tl,tm,pos,val,x);
        else
            upd_row(2*ver+1,tm+1,tr,pos,val,x);

        seg_row[x][ver]=max(seg_row[x][2*ver],seg_row[x][2*ver+1]);                
    }    
}

void upd_col(int ver,int tl,int tr,int pos,int val,int x)
{
    if(tl>tr)
        return ;
    else if(tl==tr)
    {
        seg_col[x][ver].first=min(seg_col[x][ver].first,val);
    }
    else
    {
        int tm=(tl+tr)/2;
        if(tm>=pos)
            upd_col(2*ver,tl,tm,pos,val,x);
        else
            upd_col(2*ver+1,tm+1,tr,pos,val,x);

        seg_col[x][ver]=max(seg_col[x][2*ver],seg_col[x][2*ver+1]);                
    }    
}

pair<int,int> get_row(int ver,int tl,int tr,int l,int r,int x)
{
    if(tl>tr||l>r||tr<l||r<tl)
        return {-1,0};
    else if(tl==l&&tr==r)
        return seg_row[x][ver];
    else
    {
        int tm=(tl+tr)/2;
        return max(get_row(2*ver,tl,tm,l,min(tm,r),x),get_row(2*ver+1,tm+1,tr,max(tm+1,l),r,x));
    }    
}

pair<int,int> get_col(int ver,int tl,int tr,int l,int r,int x)
{
    if(tl>tr||l>r||tr<l||r<tl)
        return {-1,0};
    else if(tl==l&&tr==r)
        return seg_col[x][ver];
    else
    {
        int tm=(tl+tr)/2;
        return max(get_col(2*ver,tl,tm,l,min(tm,r),x),get_col(2*ver+1,tm+1,tr,max(tm+1,l),r,x));
    }    
}

int n,m;
void bfs(pair<int,int>pp)
{
    dis[pp.first][pp.second]=0;
    queue<pair<int,int>> qq;
    qq.push(pp);
    while (!qq.empty())
    {
        pair<int,int>p=qq.front();
        qq.pop();
        while (1)
        {
            pair<int,int>z=get_row(1,1,m,row1[p.first][p.second],row2[p.first][p.second],p.first);
            if(z.first>dis[p.first][p.second]+1)
            {
                dis[p.first][z.second]=dis[p.first][p.second]+1;
                upd_row(1,1,m,z.second,dis[p.first][z.second],p.first);
                upd_col(1,1,n,p.first,dis[p.first][z.second],z.second);
                qq.push({p.first,z.second});
            }
            else
            {
                break;
            }            
        }
        while (1)
        {
            pair<int,int>z=get_col(1,1,n,col1[p.first][p.second],col2[p.first][p.second],p.second);
            if(z.first>dis[p.first][p.second]+1)
            {
                dis[z.second][p.second]=dis[p.first][p.second]+1;
                upd_col(1,1,n,z.second,dis[z.second][p.second],p.second);
                upd_row(1,1,m,p.second,dis[z.second][p.second],z.second);
                qq.push({z.second,p.second});
            }
            else
            {
                break;
            }            
        }        
    }    
}

signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);  
cout.tie(0);   

#ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
    freopen ("INPUT.txt" , "r" , stdin);
    freopen ("OUTPUT.txt" , "w" , stdout);
    }
#endif  

    int k;
    cin>>n>>m>>k;
    dis.resize(n+1);
    col1.resize(n+1);
    row1.resize(n+1);
    col2.resize(n+1);
    row2.resize(n+1);
    seg_row.resize(n+1);
    seg_col.resize(m+1);

    pair<int,int>st,des;

    cin>>st.first>>st.second>>des.first>>des.second;

    for(int j=1;j<=n;j++)
    for(int i=0;i<4*(m+5);i++)
    {
        seg_row[j].push_back({0,0});
    }

    for(int j=0;j<m+1;j++)
    for(int i=0;i<4*(n+5);i++)
    {
        seg_col[j].push_back({0,0});
    }

    for(int i=0;i<n+1;i++)
    {
        for(int j=0;j<m+1;j++)
        {
            dis[i].push_back(1e17);
            col1[i].push_back(0);
            row1[i].push_back(0);
            col2[i].push_back(0);
            row2[i].push_back(0);
        }
    }

    for(int i=1;i<=n;i++)
    {
        s.clear();
        cin>>a[i];
        a[i]="#"+a[i];
        for(int j=1;j<=m;j++)
            if(a[i][j]=='@')
                s.insert(j);
        for(int j=1;j<=m;j++)
        {
            if(s.size()==0)
            {
                row1[i][j]=max(j-k,1LL);
                row2[i][j]=min(m,j+k);
                continue;
            }
            auto tt=s.lower_bound(j);
            if(tt==s.end())
            {
                row2[i][j]=min(m,j+k);
            }
            else
            {
                row2[i][j]=min({m,j+k,*tt-1});
            }
            tt=s.lower_bound(j+1);
            if(tt!=s.begin())
            {
                tt--;
                row1[i][j]=max(1LL,max(*tt+1,j-k));
            }
            else
            {
                row1[i][j]=max(j-k,1LL);
            }            
        }           
    }

    for(int i=1;i<=m;i++)
    {
        s.clear();
        for(int j=1;j<=n;j++)
            if(a[j][i]=='@')
                s.insert(j);
        for(int j=1;j<=n;j++)
        {
            if(s.size()==0)
            {
                col1[j][i]=max(j-k,1LL);
                col2[j][i]=min(n,j+k);
                continue;
            }
            auto tt=s.lower_bound(j);
            if(tt==s.end())
            {
                col2[j][i]=min(n,j+k);
            }
            else
            {
                col2[j][i]=min({n,j+k,*tt-1});
            }
            tt=s.lower_bound(j+1);
            if(tt!=s.begin())
            {
                tt--;
                col1[j][i]=max(1LL,max(*tt+1,j-k));
            }
            else
            {
                col1[j][i]=max(j-k,1LL);
            }
        }    
    }


    for(int i=1;i<=n;i++)
    {
        build_row(1,1,m,i);
    }
    for(int i=1;i<=m;i++)
    {
        build_col(1,1,n,i);
    }

    upd_row(1,1,m,st.second,0,st.first);
    upd_col(1,1,n,st.first,0,st.second);

    bfs(st);

    if(dis[des.first][des.second]==1e17)
        cout<<-1;
    else
        cout<<dis[des.first][des.second];


} 
    
 


Measured memory_bytes: 732200