/*
++[---------->+<]>.-[------>+<]>-.++++++++.+++++.-[->+++++<]>-.-[--->++<]>--.+.[--->+<]>---.[->+++<]>++.++++++.-------.++++++.--[--->+<]>.-[->+++<]>-..+++++++++++++.[----->++<]>.------------.+[----->+<]>.--------.+++++++++++++.-------------.--[--->+<]>-.---[->++++<]>-.++++[->+++<]>.--[--->+<]>-.[->+++<]>++.-.+++.---.-[->+++<]>.-[--->++<]>+.++++.------.[--->+<]>---.+[----->+<]>.------------.+++++++.-------.--[--->+<]>---.+++[->+++<]>++..+++++++++.---------.-[->+++<]>.+[----->+<]>+.-------------.+++++++.+.----[->+++<]>-.
*/
#include <bits/stdc++.h>
using namespace std;

typedef long long big;
#define pbb pair<big, big>
#define pii pair<int, int>
#define fe first
#define se second
#define maxheap priority_queue
#define mset multiset
#define uset unordered_set
#define umap unordered_map
#define fr(i, s, e) for(int i = s; i < e; i++)
#define revfr(i, s, e) for(int i = s - 1; i >= e; i--)
#define speed ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define debug(text) if(do_debug) {cout << (#text) << ": " << text << endl;}
#define nl "\n"

// to make push_back easily accessible
// to make make_pair easily accessible

const big mod = 1000000007;
// const big mod = 998244353;
const big infinity = 1000000000000000000;
bool do_debug = false;


template <typename T> ostream& operator<<(ostream& os, vector<T>& v) {
	
	for(auto element : v) {

		os << element << " ";
	}

	return os;
}

template <typename T, typename S> ostream& operator<<(ostream& os, pair<T, S>& p) {
	
	os << "(" << p.first << ", " << p.second << ")";
	return os;
}

template <typename T> ostream& operator<<(ostream& os, set<T>& v) {

	if(v.size() == 0) {

		os << "empty set\n";
		return os;
	}

	auto endit = v.end();
	endit--;

	os << "[";
	
	for(auto it = v.begin(); it != v.end(); it++) {

		os << *it;

		if(it != endit) {

			os << ", ";
		}
	}

	os << "]";

	return os;
}

template <typename T> ostream& operator<<(ostream& os, multiset<T>& v) {

	if(v.size() == 0) {

		os << "empty multiset\n";
		return os;
	}

	auto endit = v.end();
	endit--;

	os << "[";
	
	for(auto it = v.begin(); it != v.end(); it++) {

		os << *it;

		if(it != endit) {

			os << ", ";
		}
	}

	os << "]";

	return os;
}

template <typename T, typename S> ostream& operator<<(ostream& os, map<T, S>& v) {

	if(v.size() == 0) {

		os << "empty map\n";
		return os;
	}
	
	auto endit = v.end();
	endit--;

	os << "{";
	
	for(auto it = v.begin(); it != v.end(); it++) {

		os << "(" << (*it).first << " : " << (*it).second << ")";

		if(it != endit) {

			os << ", ";
		}
	}

	os << "}";

	return os;
}

template <typename T> ostream& operator<<(ostream& os, vector<vector<T>>& v) {
	
	for(auto& subv : v) {

		for(auto& e : subv) {

			os << e << " ";
		}

		os << "\n";
	}

	return os;
}


typedef pair<big, pii> type;


big n, m, w;
vector<vector<big>> v;
vector<vector<big>> d1;
vector<vector<big>> d2;
big s1 = infinity;
big s2 = infinity;
vector<vector<bool>> seen;
vector<int> ch = {-1, 1, 0, 0};
vector<int> ch2 = {0, 0, -1, 1};


void rev_bfs() {

	int x = n - 1, y = m - 1;

	queue<pii> q;
	q.push(make_pair(x, y));
	seen[x][y] = true;

	while(!q.empty()) {

		x = q.front().fe;
		y = q.front().se;
		// seen[x][y] = true;
		q.pop();

		fr(i, 0, 4) {

			fr(j, i, i + 1) {

				int X = x + ch[i];
				int Y = y + ch2[j];

				if(X >= 0 && X < n && Y >= 0 && Y < m && v[X][Y] != -1 && (!seen[X][Y])) {

					q.push(make_pair(X, Y));
					d2[X][Y] = d2[x][y] + w;
					seen[X][Y] = true;

					if(v[X][Y] > 0) {

						s2 = min(s2, v[X][Y] + d2[X][Y]);
					}
				}
			}
		}
	}
}


void bfs() {

	int x = 0, y = 0;

	queue<pii> q;
	q.push(make_pair(x, y));
	seen[x][y] = true;

	while(!q.empty()) {

		x = q.front().fe;
		y = q.front().se;
		// seen[x][y] = true;
		q.pop();

		fr(i, 0, 4) {

			fr(j, i, i + 1) {

				int X = x + ch[i];
				int Y = y + ch2[j];

				if(X >= 0 && X < n && Y >= 0 && Y < m && (v[X][Y] != -1) && (!seen[X][Y])) {

					q.push(make_pair(X, Y));
					d1[X][Y] = d1[x][y] + w;
					seen[X][Y] = true;

					if(v[X][Y] > 0) {

						s1 = min(s1, v[X][Y] + d1[X][Y]);
					}
				}
			}
		}
	}
}


void solve() {

	cin >> n >> m >> w;
	v = vector<vector<big>> (n, vector<big>(m));
	d1 = vector<vector<big>> (n, vector<big>(m, infinity));
	d2 = vector<vector<big>> (n, vector<big>(m, infinity));
	d1[0][0] = 0;
	d2[n - 1][m - 1] = 0;
	seen = vector<vector<bool>> (n, vector<bool>(m, false));

	fr(i, 0, n) {

		fr(j, 0, m) {

			cin >> v[i][j];
		}
	}

	bfs();

	seen = vector<vector<bool>> (n, vector<bool>(m, false));
	rev_bfs();



	big ans = infinity;

	if(d2[0][0] != infinity) {

		ans = d2[0][0];
	}

	if(v[0][0] > 0) {

		s1 = min(s1, v[0][0]);
	}

	if(v[n - 1][m - 1] > 0) {

		s2 = min(s2, v[n - 1][m - 1]);
	}

	if(s1 != infinity && s2 != infinity) {

		ans = min(ans, s1 + s2);
	}

	// cout << d1 << nl << d2 << nl;
	// cout << s1 << nl << s2 << nl;

	if(ans == infinity) {

		cout << -1 << nl;
		return;
	}

	cout << ans << nl;
}


int main() {
	
	speed;

	int q = 1;
	// cin >> q;

	while(q-- > 0) {

		solve();
	}

	return 0;
}