#include<bits/stdc++.h>
// #pragma GCC optimize("O1")
// #pragma GCC optimize("O2")
using namespace std;
//#define ll __int128
#define ll long long 
#define debug(a,n) for(ll i = 0;i<n;i++) cout<<a[i]<<" ";
#define sum(a,n,s) for(ll i = 0;i<n;i++) s+=a[i];
#define scan(a,n) for(ll i = 0;i<n;i++) cin>>a[i];
#define fori(i,a1,a2) for(ll i = a1;i<a2;i++) 
#define ford(i,a1,a2) for(ll i = a1;i>=a2;i--)
typedef vector<pair<ll,ll>> vvpair;
typedef vector<ll> vv ;
typedef map<ll,ll> mml;
typedef vector <vector <ll>> vvov ;
#define pb push_back
#define mp make_pair
// #define && ||
void print(vector<vector<ll>> arr)
{
    cout<<"-------------"<<endl;
    for(ll i = 0;i<arr.size();i++)
    {
        for(ll j = 0;j<arr[i].size();j++)
        {
            cout<<arr[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<"-------------"<<endl;
}
void bfs(vector <vector<ll>> &arr, pair<ll,ll> start,vector<vector<ll>> &dist)
{
    // vector <ll> arr;
    ll n = arr.size();
    ll m = arr[0].size();
    // vector <ll> dist; 
    // vector <ll> temp(m,LLONG_MAX);
    // vector <vector<ll>> dist(n,temp);
    ll visited1[n][m];
    memset(visited1,0,sizeof visited1);
    dist[start.first][start.second] = 0;
    queue <pair<ll,ll>> q;
    q.push(start);
    // unordered_map <pair<ll,ll>,ll> visited;
    visited1[start.first][start.second] = 1;
    while(!q.empty())
    {
        ll i = q.front().first;
        ll j = q.front().second;
        // cout<<i<<" "<<j<<"****"<<endl;
        if(i-1>=0)
        {
            if(visited1[i-1][j]==0)
            {
                if(arr[i-1][j]!=-1)
                {
                    dist[i-1][j] = dist[i][j]+1;
                    visited1[i-1][j]=1;
                    q.push(mp(i-1,j));
                }
                // else
                // {
                //     dist[i-1][j] = LLONG_MAX;
                // }
                visited1[i-1][j]=1;
            }
        }
        if(j-1>=0)
        {
            if(visited1[i][j-1]==0)
            {
                if(arr[i][j-1]!=-1)
                {
                    dist[i][j-1] = dist[i][j]+1;
                    visited1[i][j-1]=1;
                    q.push(mp(i,j-1));
                }
                // else
                // {
                //     dist[i][j-1] = LLONG_MAX;
                // }
                visited1[i][j-1]=1;
            }
        }
        if(j+1<m)
        {
            if(visited1[i][j+1]==0)
            {
                if(arr[i][j+1]!=-1)
                {
                    dist[i][j+1] = dist[i][j]+1;
                    visited1[i][j+1]=1;
                    q.push(mp(i,j+1));
                }
                // else
                // {
                //     dist[i][j+1] = LLONG_MAX;
                // }
                visited1[i][j+1]=1;
            }
        }
        if(i+1<n)
        {
            if(visited1[i+1][j]==0)
            {
                if(arr[i+1][j]!=-1)
                {
                    dist[i+1][j] = dist[i][j]+1;
                    visited1[i+1][j]=1;
                    q.push(mp(i+1,j));
                }
                // else
                // {
                //     dist[i+1][j] = LLONG_MAX;
                // }
                visited1[i+1][j]=1;
            }
        }
        q.pop();
    }
    // print(dist);
    // return dist;

}

void solve()
{
    ll n,m,w;
    cin>>n>>m>>w;
    vector <ll> temp(m,0);
    vector <vector<ll>> arr(n,temp);
    for(ll i = 0;i<n;i++)
    {
        for(ll j = 0;j<m;j++)
        {
            cin>>arr[i][j];
        }
    }
    // cout<<""
    // print(arr);
    // print(bfs(arr,mp(0,0)));
    // print(bfs(arr,mp(m-1,n-1)));
    vector <ll> temp1(m,LLONG_MAX);
    vector <vector<ll>> dist1(n,temp1);
    vector <vector<ll>> dist2(n,temp1);
    bfs(arr,mp(0,0),dist1);
    bfs(arr,mp(n-1,m-1),dist2);
    // print(dist1);
    // print(dist2);
    // we need to find the portal minimum 
    ll dist_sor_por = LLONG_MAX;
    pair <ll,ll> dist_sor_por_ind ;
    // ll dist_dor_por = LLONG_MAX;
    // pair <ll,ll> dist_dor_por_ind ;
    ll dist_dor_por = LLONG_MAX;
    pair <ll,ll> dist_dor_por_ind ;
    for(ll i = 0;i<n;i++)
    {
        for(ll j = 0;j<m;j++)
        {
            if(arr[i][j]!=0 && arr[i][j]!=-1 && dist1[i][j]!=LLONG_MAX)
            {
                // cout<<dist1[i][j]<<"*****"<<i<<" "<<j<<endl;
                if(dist1[i][j]*w+arr[i][j]<dist_sor_por)
                {
                    dist_sor_por_ind = mp(i,j);
                    dist_sor_por = dist1[i][j]*w+arr[i][j];
                }
                // cout<<"Hello"<<endl;
            }
            if(arr[i][j]!=0 && arr[i][j]!=-1 && dist2[i][j]!=LLONG_MAX)
            {
                // cout<<dist2[i][j]<<"*****"<<i<<" "<<j<<endl;
                if(dist2[i][j]*w+arr[i][j]<dist_dor_por)
                {
                    dist_dor_por_ind = mp(i,j);
                    dist_dor_por = dist2[i][j]*w+arr[i][j];
                }
                // cout<<"Hello"<<endl;
            } 
        }
    }
    
    ll ans1 ;
    if(dist_sor_por==LLONG_MAX or dist_dor_por==LLONG_MAX)
    {
        ans1 = -1;
    }
    else
    {
        ans1 = dist_dor_por+dist_sor_por;
    }
    ll ans2;
    if(dist1[n-1][m-1]==LLONG_MAX)
    {
        ans2=-1;
    }
    else
    {
        ans2=dist1[n-1][m-1]*w;
    }
    if(ans1==-1 && ans2==-1)
    {
        cout<<-1<<endl;
    }
    else
    {
        if(ans1==-1)
        {
            cout<<ans2<<endl;
        }
        else
        {
            if(ans2==-1)
            {
                cout<<ans1<<endl;
            }
            else
            {
                cout<<min(ans1,ans2)<<endl;
            }
        }
    }
    return;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int t=1 ;
    // cin>>t;
    while(t--)
    {
        
        solve();
    }
    return 0;
}