#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>

using namespace std;

#ifdef _MSC_VER
#include <unordered_map>
#include <unordered_set>
#else
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif


#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int popcount(T n) { return n ? 1 + popcount(n & (n - 1)) : 0; }
#endif
#ifdef __GNUC__
template <class T> int popcount(T n);
template <> int popcount(unsigned int n) { return __builtin_popcount(n); }
template <> int popcount(int n) { return __builtin_popcount(n); }
template <> int popcount(unsigned long long n) { return __builtin_popcountll(n); }
template <> int popcount(long long n) { return __builtin_popcountll(n); }
#endif

#define rep (i, n) for (int i = 0; i < (int)n; ++i)
#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))


template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };
bool valid_pos(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }

template <class T> void print(T a, int n, int br = 1, const string& deli = ", ") { cout << "{ "; for (int i = 0; i < n; ++i) { cout << a[i]; if (i + 1 != n) cout << deli; } cout << " }"; while (br--) cout << endl; }
template <class T> void print(const vector<T>& v, int br = 1, const string& deli = ", ") { print(v, v.size(), br, deli); }



vector<string> remove_included(const vector<string>& s)
{
    vector<string> res;
    for (int i = 0; i < s.size(); ++i)
    {
        bool included = false;
        for (int j = 0; j < s.size(); ++j)
        {
            if (i != j && s[j].find(s[i]) != string::npos)
            {
                included = true;
                break;
            }
        }
        if (!included)
            res.push_back(s[i]);
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false);

    int n;
    while (cin >> n, n)
    {
        vector<string> s(n);
        for (int i = 0; i < n; ++i)
            cin >> s[i];
        s = remove_included(s);
        n = s.size();

        int cost[16][16];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                for (int k = 0; k < s[j].size() && k < s[i].size(); ++k)
                    if (s[i].compare(s[i].size() - k, k, s[j], 0, k) == 0)
                        cost[i][j] = s[j].size() - k;

        const int INF = 1 << 29;
        static int dp[1 << 14][14];
        for (int s = 0; s < 1 << n; ++s)
            for (int i = 0; i < n; ++i)
                dp[s][i] = INF;
        for (int i = 0; i < n; ++i)
            dp[1 << i][i] = s[i].size();

        for (int s = 1; s < 1 << n; ++s)
            for (int i = 0; i < n; ++i)
                if (s >> i & 1)
                    for (int j = 0; j < n; ++j)
                        if (s >> j & 1)
                            min_swap(dp[s][i], dp[s ^ (1 << i)][j] + cost[j][i]);

        int res = INF;
        for (int i = 0; i < n; ++i)
            min_swap(res, dp[(1 << n) - 1][i]);
        cout << res << endl;
    }
}

Measured memory_bytes: 1824