Dima overslept the alarm clock, which was supposed to raise him to school.Dima wonders if he will have time to come to the first lesson. To do this, he needs to know the minimum time it will take him to get from home to school.The city where Dima lives is a rectangular field of $$$n \times m$$$ size. Each cell $$$(i, j)$$$ on this field is denoted by one number $$$a_{ij}$$$:  The number $$$-1$$$ means that the passage through the cell is prohibited;  The number $$$0$$$ means that the cell is free and Dima can walk though it.  The number $$$x$$$ ($$$1 \le x \le 10^9$$$) means that the cell contains a portal with a cost of $$$x$$$. A cell with a portal is also considered free. From any portal, Dima can go to any other portal, while the time of moving from the portal $$$(i, j)$$$ to the portal $$$(x, y)$$$ corresponds to the sum of their costs $$$a_{ij} + a_{xy}$$$.In addition to moving between portals, Dima can also move between unoccupied cells adjacent to one side in time $$$w$$$. In particular, he can enter a cell with a portal and not use it.Initially, Dima is in the upper-left cell $$$(1, 1)$$$, and the school is in the lower right cell $$$(n, m)$$$.

The first line contains three integers $$$n$$$, $$$m$$$ and $$$w$$$ ($$$2 \le n, m \le 2 \cdot 10^3$$$, $$$1 \le w \le 10^9$$$), where $$$n$$$ and $$$m$$$ are city size, $$$w$$$ is time during which Dima moves between unoccupied cells. The next $$$n$$$ lines each contain $$$m$$$ numbers ($$$-1 \le a_{ij} \le 10^9$$$) — descriptions of cells. It is guaranteed that the cells $$$(1, 1)$$$ and $$$(n, m)$$$ are free.

Output the minimum time it will take for Dima to get to school. If he cannot get to school at all, then output "-1".

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"
	"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 (
	"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] + 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] + 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"
	"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("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"

	"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
}