package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)
var wrtr = bufio.NewWriterSize(os.Stdout, 10_000_000)
var rdr = bufio.NewScanner(os.Stdin)
func I(a int) int64 { return int64(a) }
func gs() string  { rdr.Scan(); return rdr.Text() }
func gi() int64 { i,e := strconv.ParseInt(gs(),10,64); if e != nil {panic(e)}; return i }
func gi2() (int64,int64) { return gi(),gi() }
func gi3() (int64,int64,int64) { return gi(),gi(),gi() }
func gi4() (int64,int64,int64,int64) { return gi(),gi(),gi(),gi() }
func gis(n int64) []int64 { res := make([]int64,n); for i:=I(0);i<n;i++ { res[i] = gi() }; return res }
func gf() float64 { f,e := strconv.ParseFloat(gs(),64); if e != nil {panic(e)}; return f }
func gbs() []byte { return []byte(gs()) }
func gfs(n int64) []float64  { res := make([]float64,n); for i:=I(0);i<n;i++ { res[i] = gf() }; return res }
func gss(n int64) []string  { res := make([]string,n); for i:=I(0);i<n;i++ { res[i] = gs() }; return res }
func ia(m int64) []int64 { return make([]int64,m) }
func iai(m int64,v int64) []int64 { a := make([]int64,m); for i:=I(0);i<m;i++ { a[i] = v }; return a }
func twodi(n int64,m int64,v int64) [][]int64 {
	r := make([][]int64,n); for i:=I(0);i<n;i++ { x := make([]int64,m); for j:=I(0);j<m;j++ { x[j] = v }; r[i] = x }; return r
}
func fill2(m int64) ([]int64,[]int64) { a,b := ia(m),ia(m); for i:=I(0);i<m;i++ {a[i],b[i] = gi(),gi()}; return a,b }
func fill3(m int64) ([]int64,[]int64,[]int64) { a,b,c := ia(m),ia(m),ia(m); for i:=I(0);i<m;i++ {a[i],b[i],c[i] = gi(),gi(),gi()}; return a,b,c }
func fill4(m int64) ([]int64,[]int64,[]int64,[]int64) { a,b,c,d := ia(m),ia(m),ia(m),ia(m); for i:=I(0);i<m;i++ {a[i],b[i],c[i],d[i] = gi(),gi(),gi(),gi()}; return a,b,c,d }
func abs(a int64) int64 { if a < 0 { return -a }; return a }
func rev(a []int64) { i,j := I(0),I(len(a)-1); for i < j { a[i],a[j] = a[j],a[i]; i++; j-- } }
func max(a,b int64) int64 { if a > b { return a }; return b }
func min(a,b int64) int64 { if a > b { return b }; return a }
func tern(cond bool, a int64, b int64) int64 { if cond { return a }; return b }
func terns(cond bool, a string, b string) string { if cond { return a }; return b }
func maxarr(a []int64) int64 { ans := a[0]; for _,aa := range(a) { if aa > ans { ans = aa } }; return ans }
func minarr(a []int64) int64 { ans := a[0]; for _,aa := range(a) { if aa < ans { ans = aa } }; return ans }
func sumarr(a []int64) int64 { ans := I(0); for _,aa := range(a) { ans += aa }; return ans }
func zeroarr(a []int64) { for i:=I(0); i<I(len(a)); i++ { a[i] = 0 } }
func powmod(a,e,mod int64) int64 { res, m := I(1), a; for e > 0 { if e&1 != 0 { res = res * m % mod }; m = m * m % mod; e >>= 1 }; return res }
func powint(a,e int64) int64 { res, m := I(1), a; for e > 0 { if e&1 != 0 { res = res * m }; m = m * m; e >>= 1 }; return res }
func gcd(a,b int64) int64 { for b != 0 { t:=b; b=a%b; a=t }; return a }
func gcdExtended(a,b int64) (int64,int64,int64) { if a == 0 { return b,0,1 }; gcd,x1,y1 := gcdExtended(b%a,a); return gcd, y1-(b/a)*x1,x1 }
func modinv(a,m int64) (int64,bool) { g,x,_ := gcdExtended(a,m); if g != 1 { return 0,false }; return (x % m + m) % m,true  }
func makefact(n int64,mod int64) ([]int64,[]int64) {
	fact,factinv := make([]int64,n+1),make([]int64,n+1)
	fact[0] = 1; for i:=I(1);i<=n;i++ { fact[i] = fact[i-1] * i % mod }
	factinv[n] = powmod(fact[n],mod-2,mod); for i:=n-1;i>=0;i-- { factinv[i] = factinv[i+1] * (i+1) % mod }
	return fact,factinv
}
const inf int64 = 1000000000000000000
func main() {
	//f1, _ := os.Create("cpu.prof"); pprof.StartCPUProfile(f1); defer pprof.StopCPUProfile()
	defer wrtr.Flush()
	infn := ""; if infn == "" && len(os.Args) > 1 {	infn = os.Args[1] }
	if infn != "" {	f, e := os.Open(infn); if e != nil { panic(e) }; rdr = bufio.NewScanner(f) }
	rdr.Split(bufio.ScanWords); rdr.Buffer(make([]byte,1024),1_000_000_000)
	// PROGRAM STARTS HERE
	N,M := gi(),gi(); U,V := fill2(M); for i:=I(0);i<M;i++ { U[i]--; V[i]-- }
	gr:=make([][]int64,N); grrev := make([][]int64,N)
	for i:=I(0);i<M;i++ { u,v := U[i],V[i]; gr[u] = append(gr[u],v); grrev[v] = append(grrev[v],u) }
	numdeps := make([]int64,N); for i:=I(0);i<N;i++ { numdeps[i] = I(len(gr[i])) }
	q := make([]int64,0); for i:=I(0);i<N;i++ { if numdeps[i] == 0 { q = append(q,i) } }
	ans := I(1)
	maxsuffix := make([]int64,N)
	for len(q) != 0 {
		n := q[0]; q = q[1:]
		startok := len(gr[n]) >= 2
		endok   := len(grrev[n]) >= 2
		cand := I(1)
		if startok {
			for _,c := range gr[n] { cand = max(cand,1+maxsuffix[c]) }
			ans = max(cand,ans)
		}
		if endok { maxsuffix[n] = 1 }
		if startok && endok { maxsuffix[n] = cand }
		for _,p := range grrev[n] { numdeps[p]--; if numdeps[p] == 0 { q = append(q,p) } }
	}
	fmt.Println(ans)
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

var in, out = bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)

var g [][]int
var inn, outt, dp []int

func solve() {
	var n, m int
	fmt.Fscan(in, &n, &m)
	g = make([][]int, 200009)
	inn = make([]int, 200009)
	outt = make([]int, 200009)
	dp = make([]int, 200009)
	for i := 0; i < m; i++ {
		var u, v int
		fmt.Fscan(in, &u, &v)
		g[v] = append(g[v], u)
		outt[v]++
		inn[u]++
	}
	z := make([]int, 200009)
	copy(z, inn)
	q := make([]int, 0)
	for i := 1; i <= n; i++ {
		dp[i] = 1
		if inn[i] == 0 {
			q = append(q, i)
		}
	}
	ans := 1
	for len(q) > 0 {
		x := q[0]
		q = q[1:]
		if len(g[x]) < 2 {
			if len(g[x]) == 1 {
				z[g[x][0]]--
				if z[g[x][0]] == 0 {
					q = append(q, g[x][0])
				}
			}
			ans = max(ans, dp[x])
			continue
		}
		for _, v := range g[x] {
			if inn[v] == 1 {
				q = append(q, v)
				dp[v] = max(dp[v], 1)
				ans = max(ans, dp[v])
				z[v]--
				continue
			}
			z[v]--
			dp[v] = max(dp[v], dp[x]+1)
			ans = max(ans, dp[v])
			if z[v] == 0 {
				q = append(q, v)
			}
		}
	}
	fmt.Fprintf(out, "%d\n", ans)
}

func main() {
	defer out.Flush()
	var t int
	for t = 1; t > 0; t-- {
		solve()
	}
}
func min(a int, b int) int {
	if a < b {
		return a
	}
	return b
}

func max(a int, b int) int {
	if a > b {
		return a
	}
	return b
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
	inf  = int64(1000000000000000000)
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == inf {
				memo[next.row][next.col] = memo[now.row][now.col] + w
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, inf)
	shortestEnd := InitInts2D(n, m, inf)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := inf
	ans = Min(ans, shortestStart[0][0])
	minStart := inf
	minEnd := inf
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				minStart = Min(minStart, shortestStart[i][j]+grid[i][j])
				minEnd = Min(minEnd, shortestEnd[i][j]+grid[i][j])
			}
		}
	}
	ans = Min(ans, minStart+minEnd)
	if ans == inf {
		ans = -1
	}
	fmt.Fprintln(wr, ans)
}

package main
import("bufio";."fmt";"os";"strconv")

// github.com/EndlessCheng/codeforces-go
func main(){
	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	r:=func()int{in.Scan();v,_:=strconv.Atoi(string(in.Bytes()));return v}
	vs:=[][2]int{{-1,0},{1,0},{0,-1},{0,1}}
	U:=int64(1e18)
	n,m,w,ans:=r(),r(),int64(r()),U
	d:=make([][]int,n)
	a:=make([][]int64,n)
	for i:=range d{
		d[i]=make([]int,m)
		a[i]=make([]int64,m)
		for j:=range a[i]{a[i][j]=int64(r())}
	}
	f:=func(x,y int)int64{
		for i:=range d{for j:=range d[i]{d[i][j]=-1}}
		d[x][y]=0
		for q:=[][2]int{{x,y}};len(q)>0;{
			p:=q[0];q=q[1:]
			for _,v:=range vs{
				if x,y:=p[0]+v[0],p[1]+v[1];0<=x&&x<n&&0<=y&&y<m&&d[x][y]<0&&a[x][y]>=0{
					d[x][y]=d[p[0]][p[1]]+1
					q=append(q,[2]int{x,y})
				}
			}//sahilarora
		}
		if d:=d[n-1][m-1];x==0&&d>0{ans=int64(d)*w}
		mi:=U
		for i,r:=range d{
			for j,d:=range r{
				if s:=int64(d)*w+a[i][j];d>=0&&a[i][j]>0&&s<mi{mi=s}
			}
		}
		return mi
	}
	if s:=f(0,0)+f(n-1,m-1);s<ans{ans=s}
	if ans==U{ans=-1}
	Print(ans)
}

package main

import (
	"fmt"
	"os"

)

func main() {
	scanner := SNewScanner(os.Stdin, 1<<12)
	n, m, w := int(scanner.SNextInt()), int(scanner.SNextInt()), scanner.SNextInt()
	start := make([][]int64, n)
	end := make([][]int64, n)
	mat := scanner.SNext2DInts(int64(n), int64(m))
	for i := range mat {
		start[i] = make([]int64, m)
		end[i] = make([]int64, m)
	}
	start[0][0] = 1
	processPoints(mat, start, 0, 0)

	end[n-1][m-1] = 1
	processPoints(mat, end, n-1, m-1)

	var minStart int64 = -1
	var minEnd int64 = -1
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if mat[i][j] > 0 {
				if start[i][j] != 0 && (minStart == -1 || minStart > start[i][j]*w+mat[i][j]) {
					minStart = start[i][j]*w + mat[i][j]
				}
				if end[i][j] != 0 && (minEnd == -1 || minEnd > end[i][j]*w+mat[i][j]) {
					minEnd = end[i][j]*w + mat[i][j]
				}
			}
		}
	}

	var min int64 = -1
	if start[n-1][m-1] != 0 {
		min = (start[n-1][m-1] - 1) * w
	}
	if minStart != -1 && minEnd != -1 && (min == -1 || minStart+minEnd-2*w < min) {
		min = minStart + minEnd - 2*w
	}
	fmt.Println(min)
}

type Point struct {
	i int
	j int
}

func processPoints(mat [][]int64, process [][]int64, i, j int) {
	points := []Point{{i, j}}
	for len(points) > 0 {
		i := points[0].i
		j := points[0].j
		points = points[1:]
		for _, p := range []Point{{i - 1, j}, {i + 1, j}, {i, j - 1}, {i, j + 1}} {
			i1 := p.i
			j1 := p.j
			if i1 < 0 || i1 >= len(process) {
				continue
			}
			if j1 < 0 || j1 >= len(process[0]) {
				continue
			}

			if mat[i1][j1] != -1 && process[i1][j1] == 0 {
				process[i1][j1] = process[i][j] + 1
				points = append(points, Point{i1, j1})
			}
		}
	}
}

type Reader interface {
	Read(p []byte) (n int, err error)
}

type Scanner struct {
	reader Reader
	buf    []byte
	i      int
}

func SNewScanner(r Reader, size int64) *Scanner {
	s := &Scanner{
		reader: r,
		buf:    make([]byte, size),
	}
	r.Read(s.buf)
	return s
}

func (s *Scanner) SNextByte() byte {
	defer func() { s.i++ }()
	if s.i == len(s.buf) {
		s.buf = make([]byte, len(s.buf))
		s.reader.Read(s.buf)
		s.i -= len(s.buf)
	}
	return s.buf[s.i]
}

func (s *Scanner) SNextInt() (x int64) {
	b := s.SNextByte()
	neg := false
	for ; '0' > b; b = s.SNextByte() {
		if b == '-' {
			neg = true
		}
	}
	for ; '0' <= b; b = s.SNextByte() {
		x = x*10 + int64(b&15)
	}
	if neg {
		return -x
	}
	return
}

func (s *Scanner) SNextNInts(n int64) []int64 {
	ret := make([]int64, n)
	for i := range ret {
		ret[i] = s.SNextInt()
	}
	return ret
}

func (s *Scanner) SNext2DInts(n, m int64) [][]int64 {
	ret := make([][]int64, n)
	for i := range ret {
		ret[i] = s.SNextNInts(m)
	}
	return ret
}

package main

import (
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1520G(_r io.Reader, out io.Writer) {
	_i, buf := 1<<12, make([]byte, 1<<12)
	rc := func() byte {
		if _i == 1<<12 {
			_r.Read(buf)
			_i = 0
		}
		b := buf[_i]
		_i++
		return b
	}
	r := func() (x int) {
		b := rc()
		neg := false
		for ; '0' > b; b = rc() {
			if b == '-' {
				neg = true
			}
		}
		for ; '0' <= b; b = rc() {
			x = x*10 + int(b&15)
		}
		if neg {
			return -x
		}
		return
	}
	min := func(a, b int64) int64 {
		if a < b {
			return a
		}
		return b
	}
	const inf int64 = 1e18
	type pair struct{ x, y int }
	var dir4 = []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

	n, m, w := r(), r(), int64(r())
	a := make([][]int, n)
	dis := make([][]int64, n)
	for i := range a {
		a[i] = make([]int, m)
		for j := range a[i] {
			a[i][j] = r()
		}
		dis[i] = make([]int64, m)
	}

	ans := inf
	bfsAll := func(sx, sy int) int64 {
		for i := range dis {
			for j := range dis[i] {
				dis[i][j] = -1
			}
		}
		dis[sx][sy] = 0
		q := []pair{{sx, sy}}
		for curD := w; len(q) > 0; curD += w {
			tmp := q
			q = nil
			for _, p := range tmp {
				for _, d := range dir4 {
					if x, y := p.x+d.x, p.y+d.y; 0 <= x && x < n && 0 <= y && y < m && a[x][y] >= 0 && dis[x][y] < 0 {
						dis[x][y] = curD
						q = append(q, pair{x, y})
					}
				}
			}
		}
		if sx == 0 && dis[n-1][m-1] > 0 {
			ans = dis[n-1][m-1]
		}
		mi := inf
		for i, r := range a {
			for j, v := range r {
				if v > 0 && dis[i][j] >= 0 {
					mi = min(mi, dis[i][j]+int64(v))
				}
			}
		}
		return mi
	}
	ans = min(ans, bfsAll(0, 0)+bfsAll(n-1, m-1))
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() { CF1520G(os.Stdin, os.Stdout) }

package main

import (
	"fmt"

	"bufio"
	"os"
	"strconv"
)

type item struct {
	r, c int
	d int64
}

func main() {

	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	r:=func()int{in.Scan();v,_:=strconv.Atoi(string(in.Bytes()));return v}

	//r := bufio.NewReader(os.Stdin)

	var n, m, w int

	//fmt.Fscan(r, &n, &m, &w)
	n = r()
	m = r()
	w = r()

	cells := make([][]int64, n)
	for j := 0; j < n; j++ {
		cells[j] = make([]int64, m)
		for k := 0; k < m; k++ {
			//fmt.Fscan(r, &cells[j][k])
			cells[j][k] = int64(r())
		}
	}

	//start := time.Now().UnixNano()
	fmt.Println(solve(cells, w, n, m))
	//end := time.Now().UnixNano()

	//fmt.Println((end - start)/1000000)
}

func solve(cells[][]int64, w, n, m int) int64 {
	var min int64 = 1e18

	visited := make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	var queue []*item
	queue = append(queue, &item{d:0, r : n - 1, c : m - 1})

	visited[n-1][m-1] = true

	var bestd int64 = 1e18
	bestR := -1
	bestC := -1

	for ; len(queue) > 0; {

		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestd {
				bestd = cell + d
				bestR = r
				bestC = c
			}
		}

		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
	}

	queue = []*item{}

	queue = append(queue, &item{d : 0, r : 0, c : 0})

	visited = make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	visited[0][0] = true

	var bestStartD int64 = 1e18
	bestStartR := -1
	bestStartC := -1

	foundPath := false

	for ; len(queue) > 0; {
		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if r == n - 1 && c == m - 1 {
			foundPath = true
			if d < min {
				min = d
			}
		}

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestStartD {
				bestStartD = cell + d
				bestStartR = r
				bestStartC = c
			}
		}

		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
	}

	if (bestR == -1 || bestStartR == -1)  && !foundPath{
		return -1
	} else if (bestR == -1 || bestStartR == -1) && foundPath {
		return min
	}

	if bestR == bestStartR && bestC == bestStartC {
		d := bestd + bestStartD - 2 * cells[bestR][bestC]

		if d < min {
			min  = d
		}
	}

	d := bestd + bestStartD
	if d < min {
		min = d
	}

	return min
}

package main

import (
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1520G(_r io.Reader, out io.Writer) {
	_i, buf := 1<<12, make([]byte, 1<<12)
	rc := func() byte {
		if _i == 1<<12 {
			_r.Read(buf)
			_i = 0
		}
		b := buf[_i]
		_i++
		return b
	}
	r := func() (x int) {
		b := rc()
		neg := false
		for ; '0' > b; b = rc() {
			if b == '-' {
				neg = true
			}
		}
		for ; '0' <= b; b = rc() {
			x = x*10 + int(b&15)
		}
		if neg {
			return -x
		}
		return
	}
	min := func(a, b int64) int64 {
		if a < b {
			return a
		}
		return b
	}
	const inf int64 = 1e18
	type pair struct{ x, y int }
	var dir4 = []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

	n, m, w := r(), r(), int64(r())
	a := make([][]int, n)
	dis := make([][]int64, n)
	for i := range a {
		a[i] = make([]int, m)
		for j := range a[i] {
			a[i][j] = r()
		}
		dis[i] = make([]int64, m)
	}

	ans := inf
	bfsAll := func(sx, sy int) int64 {
		for i := range dis {
			for j := range dis[i] {
				dis[i][j] = -1
			}
		}
		dis[sx][sy] = 0
		for q := []pair{{sx, sy}}; len(q) > 0; {
			p := q[0]
			q = q[1:]
			for _, d := range dir4 {
				if x, y := p.x+d.x, p.y+d.y; 0 <= x && x < n && 0 <= y && y < m && a[x][y] >= 0 && dis[x][y] < 0 {
					dis[x][y] = dis[p.x][p.y] + 1
					q = append(q, pair{x, y})
				}
			}

		}
		if sx == 0 && dis[n-1][m-1] > 0 {
			ans = dis[n-1][m-1]*w
		}
		mi := inf
		for i, r := range a {
			for j, v := range r {
				if v > 0 && dis[i][j] >= 0 {
					mi = min(mi, dis[i][j]*w+int64(v))
				}
			}
		}
		return mi
	}
	ans = min(ans, bfsAll(0, 0)+bfsAll(n-1, m-1))
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() { CF1520G(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1520G(_r io.Reader, out io.Writer) {
	in := bufio.NewScanner(_r)
	in.Split(bufio.ScanWords)
	readInt := func() (x int) {
		in.Scan()
		data := in.Bytes()
		if data[0] == '-' {
			for _, b := range data[1:] {
				x = x*10 + int(b&15)
			}
			return -x
		}
		for _, b := range data {
			x = x*10 + int(b&15)
		}
		return
	}
	min := func(a, b int64) int64 {
		if a < b {
			return a
		}
		return b
	}
	const inf int64 = 1e18
	type pair struct{ x, y int }
	var dir4 = []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

	n, m, w := readInt(), readInt(), int64(readInt())
	a := make([][]int, n)
	dis := make([][]int64, n)
	for i := range a {
		a[i] = make([]int, m)
		for j := range a[i] {
			a[i][j] = readInt()
		}
		dis[i] = make([]int64, m)
	}

	ans := inf
	bfsAll := func(sx, sy int) int64 {
		for i := range dis {
			for j := range dis[i] {
				dis[i][j] = -1
			}
		}
		dis[sx][sy] = 0
		for q := []pair{{sx, sy}}; len(q) > 0; {
			p := q[0]
			q = q[1:]
			for _, d := range dir4 {
				if x, y := p.x+d.x, p.y+d.y; 0 <= x && x < n && 0 <= y && y < m && a[x][y] >= 0 && dis[x][y] < 0 {
					dis[x][y] = dis[p.x][p.y] + 1
					q = append(q, pair{x, y})
				}
			}

		}
		if sx == 0 && dis[n-1][m-1] > 0 {
			ans = dis[n-1][m-1]*w
		}
		mi := inf
		for i, r := range a {
			for j, v := range r {
				if v > 0 && dis[i][j] >= 0 {
					mi = min(mi, dis[i][j]*w+int64(v))
				}
			}
		}
		return mi
	}
	ans = min(ans, bfsAll(0, 0)+bfsAll(n-1, m-1))
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() { CF1520G(os.Stdin, os.Stdout) }

package main

import (
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1520G(_r io.Reader, out io.Writer) {
	_i, buf := 1<<12, make([]byte, 1<<12)
	rc := func() byte {
		if _i == 1<<12 {
			_r.Read(buf)
			_i = 0
		}
		b := buf[_i]
		_i++
		return b
	}
	r := func() (x int) {
		b := rc()
		neg := false
		for ; '0' > b; b = rc() {
			if b == '-' {
				neg = true
			}
		}
		for ; '0' <= b; b = rc() {
			x = x*10 + int(b&15)
		}
		if neg {
			return -x
		}
		return
	}
	min := func(a, b int64) int64 {
		if a < b {
			return a
		}
		return b
	}
	const inf int64 = 1e18
	type pair struct{ x, y int }
	var dir4 = []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

	n, m, w := r(), r(), int64(r())
	a := make([][]int, n)
	dis := make([][]int64, n)
	for i := range a {
		a[i] = make([]int, m)
		for j := range a[i] {
			a[i][j] = r()
		}
		dis[i] = make([]int64, m)
	}

	ans := inf
	bfsAll := func(sx, sy int) int64 {
		for i := range dis {
			for j := range dis[i] {
				dis[i][j] = -1
			}
		}
		dis[sx][sy] = 0
		for q := []pair{{sx, sy}}; len(q) > 0; {
			p := q[0]
			q = q[1:]
			for _, d := range dir4 {
				if x, y := p.x+d.x, p.y+d.y; 0 <= x && x < n && 0 <= y && y < m && a[x][y] >= 0 && dis[x][y] < 0 {
					dis[x][y] = dis[p.x][p.y] + w
					q = append(q, pair{x, y})
				}
			}

		}
		if sx == 0 && dis[n-1][m-1] > 0 {
			ans = dis[n-1][m-1]
		}
		mi := inf
		for i, r := range a {
			for j, v := range r {
				if v > 0 && dis[i][j] >= 0 {
					mi = min(mi, dis[i][j]+int64(v))
				}
			}
		}
		return mi
	}
	ans = min(ans, bfsAll(0, 0)+bfsAll(n-1, m-1))
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() { CF1520G(os.Stdin, os.Stdout) }

package main
import("bufio";."fmt";"os";"strconv")

// github.com/EndlessCheng/codeforces-go
func main(){
	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	r:=func()int{in.Scan();v,_:=strconv.Atoi(string(in.Bytes()));return v}
	vs:=[][2]int{{-1,0},{1,0},{0,-1},{0,1}}
	U:=int64(1e18)
	n,m,w,ans:=r(),r(),int64(r()),U
	d:=make([][]int,n)
	a:=make([][]int64,n)
	for i:=range d{
		d[i]=make([]int,m)
		a[i]=make([]int64,m)
		for j:=range a[i]{a[i][j]=int64(r())}
	}
	f:=func(x,y int)int64{
		for i:=range d{for j:=range d[i]{d[i][j]=-1}}
		d[x][y]=0
		for q:=[][2]int{{x,y}};len(q)>0;{
			p:=q[0];q=q[1:]
			for _,v:=range vs{
				if x,y:=p[0]+v[0],p[1]+v[1];0<=x&&x<n&&0<=y&&y<m&&d[x][y]<0&&a[x][y]>=0{
					d[x][y]=d[p[0]][p[1]]+1
					q=append(q,[2]int{x,y})
				}
			}
		}
		if d:=d[n-1][m-1];x==0&&d>0{ans=int64(d)*w}
		mi:=U
		for i,r:=range d{
			for j,d:=range r{
				if s:=int64(d)*w+a[i][j];d>=0&&a[i][j]>0&&s<mi{mi=s}
			}
		}
		return mi
	}
	if s:=f(0,0)+f(n-1,m-1);s<ans{ans=s}
	if ans==U{ans=-1}
	Print(ans)
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
	inf  = int64(1000000000000000000)
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == inf {
				memo[next.row][next.col] = memo[now.row][now.col] + 1
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, inf)
	shortestEnd := InitInts2D(n, m, inf)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := inf
	if shortestStart[0][0] != inf {
		ans = Min(ans, shortestStart[0][0]*int64(w))
	}
	minStart := inf
	minEnd := inf
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				if shortestStart[i][j] != inf {
					minStart = Min(minStart, shortestStart[i][j]*w+grid[i][j])
				}
				if shortestEnd[i][j] != inf {
					minEnd = Min(minEnd, shortestEnd[i][j]*w+grid[i][j])
				}
			}
		}
	}
	if minStart != inf && minEnd != inf {
		ans = Min(ans, minStart+minEnd)
	}
	if ans == inf {
		ans = -1
	}
	fmt.Fprintln(wr, ans)
}

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
	"strconv"
)

type node struct {
	i, j int
}

var a [2000][2000]int64
var d1, d2 [2000][2000]int64
var direc [4][2]int = [4][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

const INF int64 = 1 << 60

func bfs(x, y, n, m int, d *[2000][2000]int64) {
	d[x][y] = 0
	queue := list.New()
	queue.PushBack(&node{x, y})

	var cur *node
	for queue.Len() > 0 {
		cur = queue.Remove(queue.Front()).(*node)
		for i := 0; i < 4; i++ {
			x, y = cur.i+direc[i][0], cur.j+direc[i][1]

			if x < 0 || x >= n || y < 0 || y >= m || a[x][y] == -1 {
				continue
			}

			if d[x][y] > d[cur.i][cur.j]+1 {
				d[x][y] = d[cur.i][cur.j] + 1
				queue.PushBack(&node{x, y})
			}
		}
	}
}

func main() {
	// reader := bufio.NewReader(os.Stdin)

	var n, m int
	var w int64

	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	r := func() int { in.Scan(); v, _ := strconv.Atoi(string(in.Bytes())); return v }

	// fmt.Fscanf(reader, "%d %d %d\n", &n, &m, &w)
	n, m, w = r(), r(), int64(r())

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			a[i][j] = int64(r())

			d1[i][j], d2[i][j] = INF, INF
		}
	}

	bfs(0, 0, n, m, &d1)
	bfs(n-1, m-1, n, m, &d2)

	ans := INF

	if d1[n-1][m-1] != INF {
		ans = d1[n-1][m-1] * w
	}

	mind1 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d1[i][j] != INF && a[i][j] > 0 {
				mind1 = min(mind1, d1[i][j]*w+a[i][j])
			}
		}
	}

	mind2 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d2[i][j] != INF && a[i][j] > 0 {
				mind2 = min(mind2, d2[i][j]*w+a[i][j])
			}
		}
	}

	ans = min(ans, mind1+mind2)

	if ans == INF {
		fmt.Println(-1)
	} else {
		fmt.Println(ans)
	}
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}

	return y
}

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
	"strconv"
	"sync"
)

type node struct {
	i, j int
}

var a [2000][2000]int64
var d1, d2 [2000][2000]int64
var direc [4][2]int = [4][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

const INF int64 = 1 << 60

func bfs(x, y, n, m int, d *[2000][2000]int64) {
	d[x][y] = 0
	queue := list.New()
	queue.PushBack(&node{x, y})

	var cur *node
	for queue.Len() > 0 {
		cur = queue.Remove(queue.Front()).(*node)
		for i := 0; i < 4; i++ {
			x, y = cur.i+direc[i][0], cur.j+direc[i][1]

			if x < 0 || x >= n || y < 0 || y >= m || a[x][y] == -1 {
				continue
			}

			if d[x][y] > d[cur.i][cur.j]+1 {
				d[x][y] = d[cur.i][cur.j] + 1
				queue.PushBack(&node{x, y})
			}
		}
	}
}

func main() {
	// reader := bufio.NewReader(os.Stdin)

	var n, m int
	var w int64

	in := bufio.NewScanner(os.Stdin)
	in.Split(bufio.ScanWords)
	r := func() int { in.Scan(); v, _ := strconv.Atoi(string(in.Bytes())); return v }

	// fmt.Fscanf(reader, "%d %d %d\n", &n, &m, &w)
	n, m, w = r(), r(), int64(r())

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			a[i][j] = int64(r())

			d1[i][j], d2[i][j] = INF, INF
		}
	}

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		bfs(0, 0, n, m, &d1)
		wg.Done()
	}()

	go func() {
		bfs(n-1, m-1, n, m, &d2)
		wg.Done()
	}()

	wg.Wait()

	ans := INF

	if d1[n-1][m-1] != INF {
		ans = d1[n-1][m-1] * w
	}

	mind1 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d1[i][j] != INF && a[i][j] > 0 {
				mind1 = min(mind1, d1[i][j]*w+a[i][j])
			}
		}
	}

	mind2 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d2[i][j] != INF && a[i][j] > 0 {
				mind2 = min(mind2, d2[i][j]*w+a[i][j])
			}
		}
	}

	ans = min(ans, mind1+mind2)

	if ans == INF {
		fmt.Println(-1)
	} else {
		fmt.Println(ans)
	}
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}

	return y
}

package main

import (
	"fmt"

	"time"
	"bufio"
	"os"
)

type item struct {
	r, c int
	d int64
}

type pair struct {
	d int64
	r, c int
}

func main() {

	r := bufio.NewReader(os.Stdin)

	var n, m, w int

	fmt.Fscan(r, &n, &m, &w)
	//n = 2000
	//m = 2000
	//w = 1000000000

	cells := make([][]int64, n)
	for j := 0; j < n; j++ {
		cells[j] = make([]int64, m)
		for k := 0; k < m; k++ {
			fmt.Fscan(r, &cells[j][k])
			//cells[j][k] = 1000000000
		}
	}

	start := time.Now().UnixNano()
	fmt.Println(solve(cells, w, n, m))
	end := time.Now().UnixNano()

	fmt.Println((end - start)/1000000)
}

func solve(cells[][]int64, w, n, m int) int64 {

	wr := bufio.NewWriter(os.Stderr)
	var min int64 = 1e18

	visited := make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	var queue []*item
	queue = append(queue, &item{d:0, r : n - 1, c : m - 1})

	visited[n-1][m-1] = true

	best := pair{d : 1e18, r :-1, c : -1}

	start := time.Now().UnixNano()
	for ; len(queue) > 0; {

		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < best.d {
				best.d = cell + d
				best.r = r
				best.c = c
			}
		}

		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
	}
	end := time.Now().UnixNano()
	fmt.Fprintf(wr, "First BFS execution time %d", (end - start)/1000000 )
	fmt.Fprint(wr, "\n")

	queue = []*item{}

	queue = append(queue, &item{d : 0, r : 0, c : 0})

	visited = make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	visited[0][0] = true

	bestStart := pair{d : 1e18, r :-1, c : -1}
	foundPath := false

	start = time.Now().UnixNano()
	for ; len(queue) > 0; {
		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if r == n - 1 && c == m - 1 {
			foundPath = true
			if d < min {
				min = d
			}
		}

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestStart.d {
				bestStart.d = cell + d
				bestStart.r = r
				bestStart.c = c
			}
		}

		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
	}
	end = time.Now().UnixNano()
	fmt.Fprintf(wr, "Second BFS execution time %d", (end - start)/1000000 )
	fmt.Fprint(wr, "\n")

	if (best.r == -1 || bestStart.r == -1)  && !foundPath{
		return -1
	} else if (best.r == -1 || bestStart.r == -1) && foundPath {
		return min
	}

	if best.r == bestStart.r && best.c == bestStart.c {
		d := best.d + bestStart.d - 2 * cells[best.r][best.c]

		if d < min {
			min  = d
		}
	}

	d := best.d + bestStart.d
	if d < min {
		min = d
	}

	wr.Flush()
	return min
}

package main

import (
	"fmt"

	"time"
)

type item struct {
	r, c int
	d int64
}

type pair struct {
	d int64
	r, c int
}

func main() {

	//r := bufio.NewReader(os.Stdin)

	var n, m, w int

	//fmt.Fscan(r, &n, &m, &w)
	n = 2000
	m = 2000
	w = 1000000000

	cells := make([][]int64, n)
	for j := 0; j < n; j++ {
		cells[j] = make([]int64, m)
		for k := 0; k < m; k++ {
			//fmt.Fscan(r, &cells[j][k])
			cells[j][k] = 1000000000
		}
	}

	start := time.Now().UnixNano()
	fmt.Println(solve(cells, w, n, m))
	end := time.Now().UnixNano()

	fmt.Println((end - start)/1000000)
}

func solve(cells[][]int64, w, n, m int) int64 {

	var min int64 = 1e18

	visited := make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	var queue []*item
	queue = append(queue, &item{d:0, r : n - 1, c : m - 1})

	visited[n-1][m-1] = true

	best := pair{d : 1e18, r :-1, c : -1}

	for ; len(queue) > 0; {

		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < best.d {
				best.d = cell + d
				best.r = r
				best.c = c
			}
		}

		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
	}

	queue = []*item{}

	queue = append(queue, &item{d : 0, r : 0, c : 0})

	visited = make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	visited[0][0] = true

	bestStart := pair{d : 1e18, r :-1, c : -1}
	foundPath := false

	for ; len(queue) > 0; {
		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if r == n - 1 && c == m - 1 {
			foundPath = true
			if d < min {
				min = d
			}
		}

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestStart.d {
				bestStart.d = cell + d
				bestStart.r = r
				bestStart.c = c
			}
		}

		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
	}

	if (best.r == -1 || bestStart.r == -1)  && !foundPath{
		return -1
	} else if (best.r == -1 || bestStart.r == -1) && foundPath {
		return min
	}

	if best.r == bestStart.r && best.c == bestStart.c {
		d := best.d + bestStart.d - 2 * cells[best.r][best.c]

		if d < min {
			min  = d
		}
	}

	d := best.d + bestStart.d
	if d < min {
		min = d
	}

	return min
}

package main

import (
	"fmt"
	"time"
)

type pair struct {
	d int64
	r, c int
}

type item struct {
	r, c int
	d int64
}

func main() {

	//r := bufio.NewReader(os.Stdin)

	var n, m, w int

	//fmt.Fscan(r, &n, &m, &w)
	n = 2000
	m = 2000
	w = 1000000000

	cells := make([][]int64, n)
	for j := 0; j < n; j++ {
		cells[j] = make([]int64, m)
		for k := 0; k < m; k++ {
			//fmt.Fscan(r, &cells[j][k])
			cells[j][k] = 1000000000
		}
	}

	start := time.Now().UnixNano()
	fmt.Println(solve(cells, w, n, m))
	end := time.Now().UnixNano()

	fmt.Println((end - start)/1000000)
}

func solve(cells[][]int64, w, n, m int) int64 {

	var min int64 = 1e18

	visited := make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	var queue []*item
	queue = append(queue, &item{d:0, r : n - 1, c : m - 1})

	visited[n-1][m-1] = true

	best := pair{d : 1e18, r :-1, c : -1}

	for ; len(queue) > 0; {

		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < best.d {
				best.d = cell + d
				best.r = r
				best.c = c
			}
		}

		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
	}

	queue = []*item{}

	queue = append(queue, &item{d : 0, r : 0, c : 0})

	visited = make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	visited[0][0] = true

	bestStart := pair{d : 1e18, r :-1, c : -1}
	foundPath := false

	for ; len(queue) > 0; {
		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		cell := cells[r][c]

		if r == n - 1 && c == m - 1 {
			foundPath = true
			if d < min {
				min = d
			}
		}

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestStart.d {
				bestStart.d = cell + d
				bestStart.r = r
				bestStart.c = c
			}
		}

		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r + 1, c : c})
			visited[r + 1][c] = true
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c + 1})
			visited[r][c + 1] = true
		}
		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, &item{d : d + int64(w), r : r - 1, c : c})
			visited[r - 1][c] = true
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, &item{d : d + int64(w), r : r, c : c - 1})
			visited[r][c - 1] = true
		}
	}

	if (best.r == -1 || bestStart.r == -1)  && !foundPath{
		return -1
	} else if (best.r == -1 || bestStart.r == -1) && foundPath {
		return min
	}

	if best.r == bestStart.r && best.c == bestStart.c {
		d := best.d + bestStart.d - 2 * cells[best.r][best.c]

		if d < min {
			min  = d
		}
	}

	d := best.d + bestStart.d
	if d < min {
		min = d
	}

	return min
}

package main

import (
	"bufio"
	"os"
	"fmt"
)

type pair struct {
	d int64
	r, c int
}

type item struct {
	r, c int
	d int64
}

func main() {

	r := bufio.NewReader(os.Stdin)

	var n, m, w int

	fmt.Fscan(r, &n, &m, &w)

	cells := make([][]int64, n)
	for j := 0; j < n; j++ {
		cells[j] = make([]int64, m)
		for k := 0; k < m; k++ {
			fmt.Fscan(r, &cells[j][k])
		}
	}

	fmt.Println(solve(cells, w, n, m))
}

func solve(cells[][]int64, w, n, m int) int64 {

	var min int64 = 1e18

	visited := make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	var queue []item
	queue = append(queue, item{d:0, r : n - 1, c : m - 1})

	best := pair{d : 1e18, r :-1, c : -1}

	for ; len(queue) > 0; {

		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		visited[r][c] = true

		cell := cells[r][c]

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < best.d {
				best.d = cell + d
				best.r = r
				best.c = c
			}
		}

		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, item{d : d + int64(w), r : r - 1, c : c})
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, item{d : d + int64(w), r : r, c : c - 1})
		}
		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, item{d : d + int64(w), r : r + 1, c : c})
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, item{d : d + int64(w), r : r, c : c + 1})
		}
	}

	queue = []item{}

	queue = append(queue, item{d : 0, r : 0, c : 0})

	visited = make([][]bool, len(cells))
	for i := 0; i < len(cells); i++ {
		visited[i] = make([]bool, len(cells[0]))
	}

	bestStart := pair{d : 1e18, r :-1, c : -1}
	foundPath := false

	for ; len(queue) > 0; {
		elem := queue[0]
		queue = queue[1 :]

		r := elem.r
		c := elem.c
		d := elem.d

		visited[r][c] = true

		cell := cells[r][c]

		if r == n - 1 && c == m - 1 {
			foundPath = true
			if d < min {
				min = d
			}
		}

		if cell == -1 {
			continue
		}

		if cell != 0 {
			if cell + d < bestStart.d {
				bestStart.d = cell + d
				bestStart.r = r
				bestStart.c = c
			}
		}

		if r + 1 < n && !visited[r + 1][c] {
			queue = append(queue, item{d : d + int64(w), r : r + 1, c : c})
		}
		if c + 1 < m && !visited[r][c + 1] {
			queue = append(queue, item{d : d + int64(w), r : r, c : c + 1})
		}
		if r - 1 >= 0 && !visited[r - 1][c] {
			queue = append(queue, item{d : d + int64(w), r : r - 1, c : c})
		}
		if c - 1 >= 0 && !visited[r][c - 1] {
			queue = append(queue, item{d : d + int64(w), r : r, c : c - 1})
		}
	}

	if (best.r == -1 || bestStart.r == -1)  && !foundPath{
		return -1
	} else if (best.r == -1 || bestStart.r == -1) && foundPath {
		return min
	}

	if best.r == bestStart.r && best.c == bestStart.c {
		d := best.d + bestStart.d - 2 * cells[best.r][best.c]

		if d < min {
			min  = d
		}
	}

	d := best.d + bestStart.d
	if d < min {
		min = d
	}

	return d
}

func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"fmt"
	"os"

)

func main() {
	scanner := SNewScanner(os.Stdin, 1<<12)
	n, m, w := scanner.SNextInt(), scanner.SNextInt(), scanner.SNextInt()
	start := make([][]int, n)
	end := make([][]int, n)
	mat := scanner.SNext2DInts(n, m)
	for i := range mat {
		start[i] = make([]int, m)
		end[i] = make([]int, m)
	}
	start[0][0] = 1
	processPoints(mat, start, 0, 0)

	end[n-1][m-1] = 1
	processPoints(mat, end, n-1, m-1)

	minStart := -1
	minEnd := -1
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if mat[i][j] > 0 {
				if start[i][j] != 0 && (minStart == -1 || minStart > start[i][j]*w+mat[i][j]) {
					minStart = start[i][j]*w + mat[i][j]
				}
				if end[i][j] != 0 && (minEnd == -1 || minEnd > end[i][j]*w+mat[i][j]) {
					minEnd = end[i][j]*w + mat[i][j]
				}
			}
		}
	}

	var min int = -1
	if start[n-1][m-1] != 0 {
		min = (start[n-1][m-1] - 1) * w
	}
	if minStart != -1 && minEnd != -1 && (min == -1 || minStart+minEnd-2*w < min) {
		min = minStart + minEnd - 2*w
	}
	fmt.Println(min)
}

type Point struct {
	i int
	j int
}

func processPoints(mat [][]int, process [][]int, i, j int) {
	points := []Point{{i, j}}
	for len(points) > 0 {
		i := points[0].i
		j := points[0].j
		points = points[1:]
		for _, p := range []Point{{i - 1, j}, {i + 1, j}, {i, j - 1}, {i, j + 1}} {
			i1 := p.i
			j1 := p.j
			if i1 < 0 || i1 >= len(process) {
				continue
			}
			if j1 < 0 || j1 >= len(process[0]) {
				continue
			}

			if mat[i1][j1] != -1 && process[i1][j1] == 0 {
				process[i1][j1] = process[i][j] + 1
				points = append(points, Point{i1, j1})
			}
		}
	}
}

type Reader interface {
	Read(p []byte) (n int, err error)
}

type Scanner struct {
	reader Reader
	buf    []byte
	i      int
}

func SNewScanner(r Reader, size int) *Scanner {
	s := &Scanner{
		reader: r,
		buf:    make([]byte, size),
	}
	r.Read(s.buf)
	return s
}

func (s *Scanner) SNextByte() byte {
	defer func() { s.i++ }()
	if s.i == len(s.buf) {
		s.buf = make([]byte, len(s.buf))
		s.reader.Read(s.buf)
		s.i -= len(s.buf)
	}
	return s.buf[s.i]
}

func (s *Scanner) SNextInt() (x int) {
	b := s.SNextByte()
	neg := false
	for ; '0' > b; b = s.SNextByte() {
		if b == '-' {
			neg = true
		}
	}
	for ; '0' <= b; b = s.SNextByte() {
		x = x*10 + int(b&15)
	}
	if neg {
		return -x
	}
	return
}

func (s *Scanner) SNextNInts(n int) []int {
	ret := make([]int, n)
	for i := range ret {
		ret[i] = s.SNextInt()
	}
	return ret
}

func (s *Scanner) SNext2DInts(n, m int) [][]int {
	ret := make([][]int, n)
	for i := range ret {
		ret[i] = s.SNextNInts(m)
	}
	return ret
}

package main

import (
	"fmt"
	"io"
	"os"
)

func ReadInt() int {
	var i int
	_, err := fmt.Scanf("%d", &i)
	if err != nil {
		panic(err)
	}
	return i
}

func ReadByte() byte {
	return ReadBytes(1)[0]
}

func ReadNL() byte {
	var nl byte
	for nl != 0x0a {
		nl = ReadByte()
	}
	return nl
}

func ReadBytes(n int) []byte {
	p := make([]byte, n)
	_, err := io.ReadFull(os.Stdin, p)
	if err != nil {
		panic(err)
	}
	return p
}

func main() {
	var n int
	var m int
	var w int
	_, err := fmt.Scanf("%d %d %d", &n, &m, &w)
	if err != nil {
		panic(err)
	}
	mat := make([][]int, n)
	start := make([][]int, n)
	end := make([][]int, n)
	for i := 0; i < n; i++ {
		ReadNL()
		mat[i] = make([]int, m)
		start[i] = make([]int, m)
		end[i] = make([]int, m)
		for j := 0; j < m; j++ {
			mat[i][j] = ReadInt()
		}
	}
	start[0][0] = 1
	processPoint(mat, start, 0, 0)
	end[n-1][m-1] = 1
	processPoint(mat, end, n-1, m-1)

	minStart := -1
	minEnd := -1
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if mat[i][j] > 0 {
				if start[i][j] != 0 && (minStart == -1 || minStart > start[i][j]*w+mat[i][j]) {
					minStart = start[i][j]*w + mat[i][j]
				}
				if end[i][j] != 0 && (minEnd == -1 || minEnd > end[i][j]*w+mat[i][j]) {
					minEnd = end[i][j]*w + mat[i][j]
				}
			}
		}
	}

	var min int = -1
	if start[n-1][m-1] != 0 {
		min = (start[n-1][m-1] - 1) * w
	}
	if minStart != -1 && minEnd != -1 {
		min = minStart + minEnd - 2*w
	}
	fmt.Println(min)
}

type Point struct {
	i int
	j int
}

func processPoint(mat [][]int, process [][]int, i, j int) {
	for _, p := range []Point{{i - 1, j}, {i + 1, j}, {i, j - 1}, {i, j + 1}} {
		i1 := p.i
		j1 := p.j
		if i1 < 0 || i1 >= len(mat) {
			continue
		}
		if j1 < 0 || j1 >= len(mat[0]) {
			continue
		}

		if mat[i1][j1] != -1 && (process[i1][j1] > process[i][j]+1 || process[i1][j1] == 0) {
			process[i1][j1] = process[i][j] + 1
			processPoint(mat, process, i1, j1)
		}
	}
}

package main

import (
	"fmt"
	"io"
	"os"
)

func ReadInt() int {
	var i int
	_, err := fmt.Scanf("%d", &i)
	if err != nil {
		panic(err)
	}
	return i
}

func ReadByte() byte {
	return ReadBytes(1)[0]
}

func ReadNL() byte {
	var nl byte
	for nl != 0x0a {
		nl = ReadByte()
	}
	return nl
}

func ReadBytes(n int) []byte {
	p := make([]byte, n)
	_, err := io.ReadFull(os.Stdin, p)
	if err != nil {
		panic(err)
	}
	return p
}

func main() {
	var n int
	var m int
	var w int
	_, err := fmt.Scanf("%d %d %d", &n, &m, &w)
	if err != nil {
		panic(err)
	}
	mat := make([][]int, n)
	start := make([][]int, n)
	end := make([][]int, n)
	for i := 0; i < n; i++ {
		ReadNL()
		mat[i] = make([]int, m)
		start[i] = make([]int, m)
		end[i] = make([]int, m)
		for j := 0; j < m; j++ {
			mat[i][j] = ReadInt()
		}
	}
	start[0][0] = 1
	processPoint(mat, start, 0, 0)
	end[n-1][m-1] = 1
	processPoint(mat, end, n-1, m-1)

	startPoints := []Point{}
	endPoints := []Point{}

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if mat[i][j] > 0 {
				if start[i][j] != 0 {
					startPoints = append(startPoints, Point{i, j})
				}
				if end[i][j] != 0 {
					endPoints = append(endPoints, Point{i, j})
				}
			}
		}
	}

	var min int = -1
	for _, s := range startPoints {
		for _, e := range endPoints {
			tot := start[s.i][s.j] + end[e.i][e.j] - 2 + mat[s.i][s.j] + mat[e.i][e.j]
			if min == -1 || tot < min {
				min = tot
			}
		}
	}
	fmt.Println(min)
}

type Point struct {
	i int
	j int
}

func processPoint(mat [][]int, process [][]int, i, j int) {
	for _, p := range []Point{{i - 1, j}, {i + 1, j}, {i, j - 1}, {i, j + 1}} {
		i1 := p.i
		j1 := p.j
		if i1 < 0 || i1 >= len(mat) {
			continue
		}
		if j1 < 0 || j1 >= len(mat[0]) {
			continue
		}

		if mat[i1][j1] != -1 && (process[i1][j1] > process[i][j]+1 || process[i1][j1] == 0) {
			process[i1][j1] = process[i][j] + 1
			processPoint(mat, process, i1, j1)
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
	inf  = int64(1000000000000000000)
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == int64(math.MaxInt32) {
				memo[next.row][next.col] = memo[now.row][now.col] + 1
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, math.MaxInt32)
	shortestEnd := InitInts2D(n, m, math.MaxInt32)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := inf
	ans = Min(ans, shortestStart[0][0]*int64(w))
	minStart := inf
	minEnd := inf
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				minStart = Min(minStart, shortestStart[i][j]*w+grid[i][j])
				minEnd = Min(minEnd, shortestEnd[i][j]*w+grid[i][j])
			}
		}
	}
	ans = Min(ans, minStart+minEnd)
	if ans == inf {
		ans = -1
	}
	fmt.Fprintln(wr, ans)
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == int64(math.MaxInt32) {
				memo[next.row][next.col] = memo[now.row][now.col] + 1
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, math.MaxInt32)
	shortestEnd := InitInts2D(n, m, math.MaxInt32)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := int64(math.MaxInt64)
	ans = Min(ans, shortestStart[0][0]*int64(w))
	minStart := int64(math.MaxInt64)
	minEnd := int64(math.MaxInt64)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				minStart = Min(minStart, shortestStart[i][j]*w+grid[i][j])
				minEnd = Min(minEnd, shortestEnd[i][j]*w+grid[i][j])
			}
		}
	}
	ans = Min(ans, minStart+minEnd)
	if ans == int64(math.MaxInt64) {
		ans = -1
	}
	fmt.Fprintln(wr, ans)
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == math.MaxInt32 {
				memo[next.row][next.col] = memo[now.row][now.col] + 1
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, math.MaxInt32)
	shortestEnd := InitInts2D(n, m, math.MaxInt32)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := int64(shortestStart[0][0]) * int64(w)
	minStart := int64(math.MaxInt64)
	minEnd := int64(math.MaxInt64)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				minStart = Min(minStart, shortestStart[i][j]*w+grid[i][j])
				minEnd = Min(minEnd, shortestEnd[i][j]*w+grid[i][j])
			}
		}
	}
	ans = Min(ans, minStart+minEnd)
	if ans == int64(math.MaxInt64) {
		ans = -1
	}
	fmt.Fprintln(wr, ans)
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Scanner struct {
	bScanner *bufio.Scanner
}

func NewScanner() *Scanner {
	bScanner := bufio.NewScanner(os.Stdin)
	bScanner.Split(bufio.ScanWords)
	bScanner.Buffer([]byte{}, math.MaxInt32)
	return &Scanner{
		bScanner,
	}
}
func (s *Scanner) Next() string {
	s.bScanner.Scan()
	return s.bScanner.Text()
}
func (s *Scanner) NextInt() int {
	s.bScanner.Scan()
	res, err := strconv.Atoi(s.bScanner.Text())
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInt64() int64 {
	s.bScanner.Scan()
	res, err := strconv.ParseInt(s.bScanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextFloat() float64 {
	s.bScanner.Scan()
	res, err := strconv.ParseFloat(s.bScanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return res
}
func (s *Scanner) NextInts(N int) []int {
	res := make([]int, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt()
	}
	return res
}
func (s *Scanner) NextInt64s(N int) []int64 {
	res := make([]int64, N)
	for i := 0; i < N; i++ {
		res[i] = s.NextInt64()
	}
	return res
}
func Min(nums ...int64) int64 {
	ans := int64(math.MaxInt64)
	for _, num := range nums {
		if num < ans {
			ans = num
		}
	}
	return ans
}
func Max(nums ...int64) int64 {
	ans := int64(math.MinInt64)
	for _, num := range nums {
		if num > ans {
			ans = num
		}
	}
	return ans
}

func InitInts1D(n int, val int64) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = val
	}
	return res
}
func InitInts2D(n, m int, val int64) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts1D(m, val)
	}
	return res
}
func InitInts3D(n, m, k int, val int64) [][][]int64 {
	res := make([][][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = InitInts2D(m, k, val)
	}
	return res
}

type coor struct {
	row, col int
}

const (
	maxn = 2005
)

var (
	n, m int
	w    int64
	grid [][]int64
	dr   = [4]int{1, 0, -1, 0}
	dc   = [4]int{0, 1, 0, -1}
)

func bfs(init coor, memo [][]int64) {
	queue := make([]coor, 0)
	queue = append(queue, init)
	memo[init.row][init.col] = 0
	for len(queue) > 0 {
		now := queue[0]
		queue = queue[1:]

		for i := 0; i < 4; i++ {
			next := coor{
				row: now.row + dr[i],
				col: now.col + dc[i],
			}
			if 0 <= next.row && next.row < n && 0 <= next.col && next.col < m && grid[next.row][next.col] != -1 && memo[next.row][next.col] == math.MaxInt32 {
				memo[next.row][next.col] = memo[now.row][now.col] + 1
				queue = append(queue, next)
			}
		}
	}
}

func main() {
	sc := NewScanner()
	wr := bufio.NewWriter(os.Stdout)
	defer wr.Flush()

	n = sc.NextInt()
	m = sc.NextInt()
	w = sc.NextInt64()
	grid = InitInts2D(n, m, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			grid[i][j] = sc.NextInt64()
		}
	}

	shortestStart := InitInts2D(n, m, math.MaxInt32)
	shortestEnd := InitInts2D(n, m, math.MaxInt32)
	bfs(coor{n - 1, m - 1}, shortestStart)
	bfs(coor{0, 0}, shortestEnd)

	ans := int64(shortestStart[0][0]) * int64(w)
	minStart := int64(math.MaxInt64)
	minEnd := int64(math.MaxInt64)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] > 0 {
				minStart = Min(minStart, shortestStart[i][j]*w+grid[i][j])
				minEnd = Min(minEnd, shortestEnd[i][j]*w+grid[i][j])
			}
		}
	}
	ans = Min(ans, minStart+minEnd)
	fmt.Fprintln(wr, ans)
}

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
)

type node struct {
	i, j int
}

var a [2000][2000]int64
var d1, d2 [2000][2000]int64
var direc [4][2]int = [4][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}

const INF int64 = 1 << 31

func bfs(x, y, n, m int, d *[2000][2000]int64) {
	d[x][y] = 0
	queue := list.New()
	queue.PushBack(&node{x, y})

	var cur *node
	for queue.Len() > 0 {
		cur = queue.Remove(queue.Front()).(*node)
		for i := 0; i < 4; i++ {
			x, y = cur.i+direc[i][0], cur.j+direc[i][1]

			if x < 0 || x >= n || y < 0 || y >= m || a[x][y] == -1 {
				continue
			}

			if d[x][y] > d[cur.i][cur.j]+1 {
				d[x][y] = d[cur.i][cur.j] + 1
				queue.PushBack(&node{x, y})
			}
		}
	}
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	var n, m int
	var w int64

	fmt.Fscanf(reader, "%d %d %d\n", &n, &m, &w)

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if j+1 == m {
				fmt.Fscanf(reader, "%d\n", &a[i][j])
			} else {
				fmt.Fscanf(reader, "%d ", &a[i][j])
			}

			d1[i][j], d2[i][j] = INF, INF
		}
	}

	bfs(0, 0, n, m, &d1)
	bfs(n-1, m-1, n, m, &d2)

	ans := d1[n-1][m-1] * w

	mind1 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d1[i][j] != INF && a[i][j] > 0 {
				mind1 = min(mind1, d1[i][j]*w+a[i][j])
			}
		}
	}

	mind2 := INF
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if d2[i][j] != INF && a[i][j] > 0 {
				mind2 = min(mind2, d2[i][j]*w+a[i][j])
			}
		}
	}

	ans = min(ans, mind1+mind2)

	if ans >= INF {
		fmt.Println(-1)
	} else {
		fmt.Println(ans)
	}
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}

	return y
}