Buggy python submission (verdict: Runtime Error):
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        for j in range(i+1, n):
            if S[i].find(S[j])+1:
                dup[j] = 1
            if S[j].find(S[i])+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    for i in range(n):
        for j in range(n):
            l = len(S[i])
            pos = l
            for k in range(l):
                if S[j].startswith(S[i][k:]):
                    pos = k
                    break
            P[i][j] = pos

    dp = {(1 << i, i): 0 for i in range(n)}
    for state in range(2**n-1):
        for i in range(n):
            if (state >> i) & 1 < 1:
                continue
            for j in range(n):
                if (state >> j) & 1 < 1:
                    dp[state | (1 << j), j] = min(
                            dp.get((state | (1 << j), j), 10**18),
                            dp[state, i] + P[i][j]
                            )
    print(min(dp[2**n-1, i] + len(S[i]) for i in range(n)))

Fixed submission:
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        si = S[i]
        for j in range(i+1, n):
            sj = S[j]
            if si.find(sj)+1:
                dup[j] = 1
            if sj.find(si)+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    for i in range(n):
        si = S[i]
        l = len(si)
        for j in range(n):
            sj = S[j]
            pos = l
            for k in range(l):
                if sj.startswith(si[k:]):
                    pos = k
                    break
            P[i][j] = len(sj) - (l - pos)

    ALL = 2**n - 1
    up = 300
    memo = {(ALL, i): 0 for i in range(n)}
    def dfs(state, i):
        if (state, i) in memo:
            return memo[state, i]
        res = up
        for j in range(n):
            if (state >> j) & 1 < 1:
                res = min(res, dfs(state | (1 << j), j) + P[i][j])
        memo[state, i] = res
        return res
    print(min(dfs(1 << i, i) + len(S[i]) for i in range(n)))

Buggy python submission (verdict: Runtime Error):
from heapq import heappush, heappop, heapify
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        for j in range(i+1, n):
            if S[i].find(S[j])+1:
                dup[j] = 1
            if S[j].find(S[i])+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    for i in range(n):
        for j in range(n):
            l = len(S[i])
            pos = l
            for k in range(l):
                if S[j].startswith(S[i][k:]):
                    pos = k
                    break
            P[i][j] = len(S[j]) - (l - pos)

    que = [(len(S[i]), 1 << i, i) for i in range(n)]
    heapify(que)

    ALL = 2**n-1
    INF = 10**18
    memo = {(1 << i, i): len(S[i]) for i in range(n)}
    while que:
        l, state, i = heappop(que)
        if memo[state, i] < l:
            continue
        if state == ALL:
            print(l)
            break
        for j in range(n):
            if (state >> j) & 1 < 1:
                key = (state | (1 << j), j)
                if l + P[i][j] < memo.get(key, INF):
                    memo[key] = l + P[i][j]
                    heappush(que, (l + P[i][j], state | (1 << j), j))

Fixed submission:
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        si = S[i]
        for j in range(i+1, n):
            sj = S[j]
            if si.find(sj)+1:
                dup[j] = 1
            if sj.find(si)+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    for i in range(n):
        si = S[i]
        l = len(si)
        for j in range(n):
            sj = S[j]
            pos = l
            for k in range(l):
                if sj.startswith(si[k:]):
                    pos = k
                    break
            P[i][j] = len(sj) - (l - pos)

    ALL = 2**n - 1
    up = 300
    memo = {(ALL, i): 0 for i in range(n)}
    def dfs(state, i):
        if (state, i) in memo:
            return memo[state, i]
        res = up
        for j in range(n):
            if (state >> j) & 1 < 1:
                res = min(res, dfs(state | (1 << j), j) + P[i][j])
        memo[state, i] = res
        return res
    print(min(dfs(1 << i, i) + len(S[i]) for i in range(n)))

Buggy python submission (verdict: Runtime Error):
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        si = S[i]
        for j in range(i+1, n):
            sj = S[j]
            if si.find(sj)+1:
                dup[j] = 1
            if sj.find(si)+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    D = [[0]*n for i in range(n)]
    for i in range(n):
        si = S[i]
        l = len(si)
        for j in range(n):
            sj = S[j]
            pos = l
            for k in range(l):
                if sj.startswith(si[k:]):
                    pos = k
                    break
            P[i][j] = len(sj) - (l - pos)
            D[i][j] = l - pos

    Q = [[] for i in range(300)]
    for i in range(n):
        Q[len(S[i])].append((1 << i, i, 0))
    ALL = 2**n-1
    up = sum(map(len, S))
    border = up
    memo = {(1 << i, i): len(S[i]) for i in range(n)}
    l = 0
    while l < border:
        for state, i, d in Q[l]:
            if memo[state, i] < l:
                continue
            for j in range(n):
                if (state >> j) & 1 < 1:
                    ncost = l + P[i][j]
                    nstate = state | (1 << j)
                    if (nstate, j) not in memo or ncost < memo[nstate, j]:
                        border = min(border, up - d - D[i][j])
                        if ncost <= border:
                            memo[nstate, j] = ncost
                            Q[ncost].append((nstate, j, d+D[i][j]))
        l += 1
    print(border)

Fixed submission:
while 1:
    n = int(input())
    if n == 0:
        break
    S = [input() for i in range(n)]

    dup = [0]*n
    for i in range(n):
        si = S[i]
        for j in range(i+1, n):
            sj = S[j]
            if si.find(sj)+1:
                dup[j] = 1
            if sj.find(si)+1:
                dup[i] = 1
    S = [S[i] for i in range(n) if not dup[i]]
    n -= sum(dup)

    P = [[0]*n for i in range(n)]
    for i in range(n):
        si = S[i]
        l = len(si)
        for j in range(n):
            sj = S[j]
            pos = l
            for k in range(l):
                if sj.startswith(si[k:]):
                    pos = k
                    break
            P[i][j] = len(sj) - (l - pos)

    ALL = 2**n - 1
    up = 300
    memo = {(ALL, i): 0 for i in range(n)}
    def dfs(state, i):
        if (state, i) in memo:
            return memo[state, i]
        res = up
        for j in range(n):
            if (state >> j) & 1 < 1:
                res = min(res, dfs(state | (1 << j), j) + P[i][j])
        memo[state, i] = res
        return res
    print(min(dfs(1 << i, i) + len(S[i]) for i in range(n)))