#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
#include<cassert>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
const int maxn = 16+5;
const int maxlen = 100 + 5;
struct Item {
string s, rev;
bool operator<(const Item &rhs) {
return s.length() < rhs.s.length();
}
};
int n;
string s[maxn][2];
int len[maxn];
int overlap[maxn][maxn][2][2];
int calc_overlap(const string&a, const string &b) {
int n1 = a.length();
int n2 = b.length();
for (int i = 1; i < n1; i++) {//从i开始往后判断a是否与b相等
if (n2 + i <= n1)continue;
bool ok = true;
for (int j = 0; i + j < n1; j++) {
if (a[i + j] != b[j]) {
ok = false; break;
}
}
if (ok)return n1 = i;
}
return 0;
}
void init() {
Item tmp[maxn];
REP(i, n) {
cin >> tmp[i].s;
tmp[i].rev = tmp[i].s;
reverse(tmp[i].rev.begin(), tmp[i].rev.end());
}
int n2 = 0;
//预处理,将包含于其他字符串的字串删除
sort(tmp, tmp + n);
REP(i, n) {
bool need = true;
for (int j = i + 1; j < n; j++) {
if (tmp[j].s.find(tmp[i].s) != string::npos || tmp[j].rev.find(tmp[i].s) != string::npos) {
need = false; break;
}
}
if (need) {//如果不是重复就加入数组
s[n2][0] = tmp[i].s;
s[n2][1] = tmp[i].rev;
len[n2] = tmp[i].s.length();
n2++;
}
}
n = n2;
REP(i, n)REP(j, n)REP(x, 2)REP(y, 2)
overlap[i][j][x][y] = calc_overlap(s[i][x],s[j][y]);
}
int d[1 << maxn][maxn][2];
inline void update(int &x, int v) {
if (x < 0 || v < x)x = v;
}
void solve() {
memset(d, -1, sizeof(d));
d[1][0][0] = len[0];
int full = (1 << n) - 1;
for (int s = 1; s < full; s++) {
REP(i,n)REP(x,2)//枚举尾部
if (d[s][i][x] >= 0) {
for (int j = 1; j < n; j++) {
if (!(s&(1 << j))) {//枚举新加人的字串
REP(y, 2)update(d[s | 1 << j][j][y], d[s][i][x] + len[j] - overlap[i][j][x][y]);//更新最小值
}
}
}
}
int ans = -1;
REP(i,n)
REP(x, 2) {
if (d[full][i][x] < 0)continue;
update(ans, d[full][i][x] - overlap[i][0][x][0]);//len[0]一开始就加过了
}
if (ans <= 1)ans = 2;
cout << ans << endl;
}
int main() {
while (cin >> n && n) {
init();
solve();
}
return 0;
}