Buggy python submission (verdict: Runtime Error):
INF = 10 ** 20

def minimum_cost(now, visited):
  if (now, visited) in dp:
    return dp[(now, visited)]
  if visited == end:
    return 0
  
  ret = INF
  for to in range(1, n + 1):
    if to not in visited:
      ret = min(ret, minimum_cost(to, tuple(sorted(list(visited) + [to]))) + cost(to, visited))
  dp[(now, visited)] = ret
  return ret

def cost(to, visited):
  return min(tlst[to - 1][i] for i in visited)

while True:
  n = int(input())
  if n == 0:
    break
  tlst = [list(map(int, input().split())) for _ in range(n)]
  dp = {}
  end = tuple(i for i in range(n + 1))
  ans = INF
  for i in range(1, n + 1):
    ans = min(ans, minimum_cost(i, (0, i)) + tlst[i - 1][0])
  print(ans)


Fixed submission:
INF = 10 ** 20

def minimum_cost(rest, dp, tlst, tord, end, n):
  if rest in dp:
    return dp[rest]
  if rest == end:
    return 0
  
  ret = INF
  for ind, to in enumerate(rest):
    if to == "0":
      tmp = minimum_cost(rest[:ind] + "1" + rest[ind + 1:], dp, tlst, tord, end, n) + cost(ind, rest, tlst, tord, n)
      if tmp < ret:
        ret = tmp
  dp[rest] = ret
  return ret

def cost(ind, rest, tlst, tord, n):
  order = tord[ind - 1]
  for i in order:
    if rest[i] == "1":
      return tlst[ind - 1][i]


def main():
  while True:
    n = int(input())
    if n == 0:
      break
    tlst = [list(map(int, input().split())) for _ in range(n)]
    tord = []
    for lst in tlst:
      tmp = sorted(zip(lst, range(n + 1)))
      tord.append([i for _, i in tmp])
    dp = {}
    end = "1" * (n + 1)
    ans = minimum_cost("1" + "0" * n, dp, tlst, tord, end, n)
    print(ans)

main()

Buggy python submission (verdict: Runtime Error):
INF = 10 ** 20

def minimum_cost(rest, dp, tlst, end, n):
  if rest in dp:
    return dp[rest]
  if rest == end:
    return 0
  
  ret = INF
  for ind, to in enumerate(rest):
    if to == "0":
      tmp = minimum_cost(rest[:ind] + "1" + rest[ind + 1:], dp, tlst, end, n) + cost(ind, rest, tlst, n)
      if tmp < ret:
        ret = tmp
  dp[rest] = ret
  return ret

def cost(ind, rest, tlst, n):
  ts = tlst[ind - 1]
  ret = INF
  for c, v in zip(rest, ts):
    if v < ret and c == "1":
      ret = v
  return ret


def main():
  while True:
    n = int(input())
    if n == 0:
      break
    tlst = [list(map(int, input().split())) for _ in range(n)]
    dp = {}
    end = "1" * (n + 1)
    ans = minimum_cost("1" + "0" * n, dp, tlst, end, n)
    print(ans)

main()


Fixed submission:
INF = 10 ** 20

def minimum_cost(rest, dp, tlst, tord, end, n):
  if rest in dp:
    return dp[rest]
  if rest == end:
    return 0
  
  ret = INF
  for ind, to in enumerate(rest):
    if to == "0":
      tmp = minimum_cost(rest[:ind] + "1" + rest[ind + 1:], dp, tlst, tord, end, n) + cost(ind, rest, tlst, tord, n)
      if tmp < ret:
        ret = tmp
  dp[rest] = ret
  return ret

def cost(ind, rest, tlst, tord, n):
  order = tord[ind - 1]
  for i in order:
    if rest[i] == "1":
      return tlst[ind - 1][i]


def main():
  while True:
    n = int(input())
    if n == 0:
      break
    tlst = [list(map(int, input().split())) for _ in range(n)]
    tord = []
    for lst in tlst:
      tmp = sorted(zip(lst, range(n + 1)))
      tord.append([i for _, i in tmp])
    dp = {}
    end = "1" * (n + 1)
    ans = minimum_cost("1" + "0" * n, dp, tlst, tord, end, n)
    print(ans)

main()