```go
package main
import (
"bufio"
"fmt"
"math"
"os"
"strconv"
)
func max(a, b int) int {
if a > b {
return a
}
return b
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
grid := make([][]int, n)
for i := 0; i < n; i++ {
grid[i] = make([]int, n)
for j := 0; j < n; j++ {
scanner.Scan()
grid[i][j], _ = strconv.Atoi(scanner.Text())
}
}
dp := make([][]int, n)
newDp := make([][]int, n)
for i := 0; i < n; i++ {
dp[i] = make([]int, n)
newDp[i] = make([]int, n)
for j := 0; j < n; j++ {
dp[i][j] = math.MinInt64
}
}
dp[0][0] = grid[0][0]
for t := 1; t <= 2*n-2; t++ {
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
newDp[i][j] = math.MinInt64
}
}
minI := t - (n - 1)
if minI < 0 {
minI = 0
}
maxI := t
if maxI > n-1 {
maxI = n - 1
}
for i1 := minI; i1 <= maxI; i1++ {
j1 := t - i1
for i2 := minI; i2 <= maxI; i2++ {
j2 := t - i2
val := grid[i1][j1]
if i1 != i2 {
val += grid[i2][j2]
}
best := math.MinInt64
if i1 > 0 && i2 > 0 {
best = max(best, dp[i1-1][i2-1])
}
if i1 > 0 && i2 <= t-1 {
best = max(best, dp[i1-1][i2])
}
if i1 <= t-1 && i2 > 0 {
best = max(best, dp[i1][i2-1])
}
if i1 <= t-1 && i2 <= t-1 {
best = max(best, dp[i1][i2])
}
if best != math.MinInt64 {
newDp[i1][i2] = best + val
}
}
}
dp, newDp = newDp, dp
}
fmt.Println(dp[n-1][n-1])
}
```