← Home
package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())

	c := make([][]int64, n+2)
	for i := range c {
		c[i] = make([]int64, n+2)
	}

	for i := 1; i <= n; i++ {
		scanner.Scan()
		parts := strings.Fields(scanner.Text())
		for j := 1; j <= n; j++ {
			val, _ := strconv.ParseInt(parts[j-1], 10, 64)
			c[i][j] = val
		}
	}

	row_sum := make([][]int64, n+2)
	col_sum := make([][]int64, n+2)
	P := make([][]int64, n+2)
	for i := 0; i <= n+1; i++ {
		row_sum[i] = make([]int64, n+2)
		col_sum[i] = make([]int64, n+2)
		P[i] = make([]int64, n+2)
	}

	for i := 1; i <= n; i++ {
		for j := 1; j <= n; j++ {
			row_sum[i][j] = row_sum[i][j-1] + c[i][j]
		}
	}

	for j := 1; j <= n; j++ {
		for i := 1; i <= n; i++ {
			col_sum[i][j] = col_sum[i-1][j] + c[i][j]
		}
	}

	for i := 1; i <= n; i++ {
		for j := 1; j <= n; j++ {
			P[i][j] = P[i-1][j] + P[i][j-1] - P[i-1][j-1] + c[i][j]
		}
	}

	const INF int64 = 1 << 60
	dp := make([][]int64, n+2)
	root := make([][]int, n+2)
	for i := range dp {
		dp[i] = make([]int64, n+2)
		root[i] = make([]int, n+2)
		for j := range dp[i] {
			dp[i][j] = INF
		}
	}

	for i := 1; i <= n; i++ {
		dp[i][i] = 0
		dp[i][i-1] = 0
		root[i][i] = i
	}

	for length := 2; length <= n; length++ {
		for l := 1; l <= n-length+1; l++ {
			r := l + length - 1
			for k := l; k <= r; k++ {
				left_cost := dp[l][k-1]
				right_cost := dp[k+1][r]

				var sum_left_to_k int64 = 0
				if k > l {
					sum_left_to_k = col_sum[k-1][k] - col_sum[l-1][k]
				}

				var sum_right_to_k int64 = 0
				if k < r {
					sum_right_to_k = row_sum[k][r] - row_sum[k][k]
				}

				var rect_sum int64 = 0
				if k > l && k < r {
					rect_sum = P[k-1][r] - P[l-1][r] - P[k-1][k] + P[l-1][k]
				}

				total := left_cost + right_cost + sum_left_to_k + sum_right_to_k + 2*rect_sum

				if total < dp[l][r] {
					dp[l][r] = total
					root[l][r] = k
				}
			}
		}
	}

	parent := make([]int, n+1)
	var build func(l, r, p int)
	build = func(l, r, p int) {
		if l > r {
			return
		}
		k := root[l][r]
		parent[k] = p
		build(l, k-1, k)
		build(k+1, r, k)
	}
	build(1, n, 0)

	out := make([]string, n)
	for i := 1; i <= n; i++ {
		out[i-1] = strconv.Itoa(parent[i])
	}
	fmt.Println(strings.Join(out, " "))
}