#define _CRT_SECURE_NO_WARNINGS
//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(ll i=a; i<ll(b); i++)
#define rep(i,b) loop(i,0,b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template<class T> istream & operator>>(istream & is, vector<T> &);
template<class T> ostream & operator<<(ostream & os, vector<T> const &);
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":" ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream & os, tuple<T...> const & t){ _ot<0>(os, t); return os; }
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _it(istream &, tuple<T...> &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _it(istream & is, tuple<T...> & t){ is >> get<n>(t); _it<n+1>(is, t); }
template<class...T> istream & operator>>(istream & is, tuple<T...> & t){ _it<0>(is, t); return is; }
template<class T, class U> istream & operator<<(istream & is, pair<T,U> & p){ return is >> p.first >> p.second; }
template<class T, class U> ostream & operator<<(ostream & os, pair<T,U> const & p){ return os << "(" << p.first << ", " << p.second << ") "; }
template<class T> istream & operator>>(istream & is, vector<T> & v){ rep(i,v.size()) is >> v[i]; return is; }
template<class T> ostream & operator<<(ostream & os, vector<T> const & v){ rep(i,v.size()) os << v[i] << (i+1==(int)v.size()?"":" "); return os; }
#ifdef DEBUG
#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<mt(__VA_ARGS__)<<" ["<<__LINE__<<"]"<<endl)
#else
#define dump(...)
#endif

typedef int Weight;
struct Edge {
    int src, dst;
    Weight weight;
    Edge(int src_, int dst_, Weight weight_) :
        src(src_), dst(dst_), weight(weight_) { }
};
bool operator < (const Edge &e, const Edge &f) {
    return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
        e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void outputGraph(const Graph & g, string const & name){
    int n = g.size();
    FILE * fp = fopen(string(name + ".txt").c_str(), "w");
    if(fp == nullptr) return;
    fprintf(fp,"digraph {\n");
    rep(i,n){
        for(auto & e : g[i]){
            fprintf(fp, "\t\"%d\" -> \"%d\" [ label = \"%d\" ];\n", e.src, e.dst, e.weight);
        }
    }
    fprintf(fp, "}\n");
    fclose(fp);
}

int const inf = 1<<29;
const int M = 20;
Weight best[1<<M][M];
int    pre[1<<M][M];
void buildPath(int S, int i, vector<int> &path) {
    if (!S) return;
    buildPath(S^(1<<i), pre[S][i], path);
    path.push_back(i);
}
Weight shortestHamiltonPath(Matrix w, int s, vector<int> &path) {
    int n = w.size();
    int N = 1 << n;
    rep(S,N) rep(i,n) best[S][i] = inf;
    best[1<<s][s] = 0;
    rep(S,N) rep(i,n) if (S&(1<<i))
        rep(j,n)
            if (best[S|(1<<j)][j] > best[S][i] + w[i][j])
                best[S|(1<<j)][j] = best[S][i] + w[i][j],
                    pre[S|(1<<j)][j] = i;
    int t = min_element(best[N-1], best[N-1]+n) - best[N-1];
    path.clear(); buildPath(N-1, t, path);
    return best[N-1][t];
}


int main(){
#ifdef LOCAL
    freopen("in","r",stdin);
#endif
    int cnt = 0;
    int n;
    while(cin >> n && n){
        vector<string> s(n);
        cin >> s;
        rep(i,n)rep(j,n)if(i!=j){
            if(s[i].find(s[j])!=string::npos){
                s[j] = "~"+s[j];
            }
        }
        s.erase(remove_if(all(s),[](const string & x){
                    return x[0] == '~';
                }), s.end());
        s.pb("");
        n = s.size();
        Matrix g(n,Array(n));
        rep(i,n)rep(j,n) g[i][j] = inf;
        rep(i,n)rep(j,n)if(i!=j){
            int same = 0;
            for(int k=1;k<=(int)s[i].size();k++){
                if(s[i].substr(s[i].size()-k,k) == s[j].substr(0,k)){
                    same = k;
                }
            }
            g[i][j] = s[j].size()-same;
        }
        int ans = inf;
        rep(i,n){
            vi v;
            ans = shortestHamiltonPath(g,i,v);
        }
        char buf[20];
        cout << ans << endl;
        sprintf(buf, "graph%0d", cnt++);
        // outputGraph(g, buf);
    }
}

Measured memory_bytes: 9456