import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n, minSum = Integer.MAX_VALUE;
static int[][] map;
static boolean[] used;
public static void main(String[] args) throws Exception {
init();
process();
print();
}
private static void init() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
map = new int[n][n];
StringTokenizer st;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
}
private static void process() {
for (int i = 0; i < n; i++) {
used = new boolean[n];
used[i] = true;
dfs(1, i, i, 0);
}
}
private static void dfs(int depth, int start, int now, int sum) {
// 현재 비용의 합이 최소 비용보다 크다면 가지치기
if (sum > minSum) {
return;
}
// 전부 순회한 경우 최솟값 갱신
if (depth == n && map[now][start] != 0) {
sum += map[now][start];
minSum = Math.min(sum, minSum);
return;
}
// 현재 위치에서 갈 수 있는 모든 정점 탐색 수행
for (int i = 0; i < n; i++) {
if (!used[i] && map[now][i] != 0) {
used[i] = true;
dfs(depth + 1, start, i, sum + map[now][i]);
used[i] = false;
}
}
}
private static void print() {
System.out.println(minSum);
}
}
마지막 도시에서 출발 도시로 가는 경우는 무조건 존재하는 것으로 착각하였음