#include <bits/stdc++.h>
using namespace std;
#define vec vector

using ll = long long;
ll n, m, w;

const vector<pair<int, int>> dirs{
    { 1 ,0 }, { -1, 0 }, { 0, 1 } , { 0, -1 }
};

void bfs(vector<vector<int>>& arr, vector<vector<ll>>& cost, int x, int y) {
    queue<pair<int, int>> q;
    vector<vector<bool>> vis(n, vector<bool>(m, false));
    vis[x][y] = 1;
    q.push({ x, y });
    cost[x][y] = 0;

    while (!q.empty()) {
        auto [i, j] = q.front();
        q.pop();


        for (auto& [dx, dy] : dirs) {
            int px = i + dx, py = j + dy;
            if (px < 0 || px >= n || py < 0 || py >= m) continue;
            if (arr[px][py] == -1) continue;
            if (vis[px][py]) continue; // cost[px][py] <= cost[i][j] + w) continue;

            vis[px][py] = 1;

            cost[px][py] = cost[i][j] + w;
            q.push({ px, py });
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin >> n >> m >> w;


    vector<vector<int>> arr(n, vector<int>(m));
    for (auto& i : arr)
        for (auto& j : i)
            cin >> j;

    ll ans = LLONG_MAX;
    vec<vec<ll>> frombeg(n, vec<ll>(m, LLONG_MAX));
    frombeg[0][0] = 0;
    bfs(arr, frombeg, 0, 0);
    ans = frombeg[n - 1][m - 1];

    ll bestBegCost = LLONG_MAX;
    vector<vector<ll>> begCostsPortal;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (arr[i][j] < 1 || frombeg[i][j] == LLONG_MAX) continue;
            bestBegCost = min(bestBegCost, frombeg[i][j] + (ll)arr[i][j]);

            //begCostsPortal.push_back({ frombeg[i][j] + arr[i][j] });
        }
    }

    //sort(begCostsPortal.begin(), begCostsPortal.end());


    vec<vec<ll>> fromend(n, vec<ll>(m, LLONG_MAX));
    fromend[n - 1][m - 1] = 0;
    bfs(arr, fromend, n - 1, m - 1);

    vector<vector<ll>> endCostsPortal;
    ll bestEndCost = LLONG_MAX;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (arr[i][j] < 1 || fromend[i][j] == LLONG_MAX) continue;
            bestEndCost = min(bestEndCost, fromend[i][j] + (ll)arr[i][j]);

            //endCostsPortal.push_back({ fromend[i][j] + arr[i][j] });
        }
    }
    //sort(endCostsPortal.begin(), endCostsPortal.end());

    //if (!begCostsPortal.empty() && !endCostsPortal.empty()) {
    if (bestBegCost < LLONG_MAX && bestEndCost < LLONG_MAX) {
        //ans = min(ans, begCostsPortal[0][0] + endCostsPortal[0][0]);
        ans = min(ans, bestBegCost + bestEndCost);
    }

    if (ans == LLONG_MAX) cout << -1;
    else cout << ans;
}