#include <bits/stdc++.h>
using namespace std;

int n, *l; char **a;
int mrg[15][15];
int total;
bool ind[15];
string str[15];

int contained(string a, string b) {
    if (a.size() > b.size()) return 0;
    int ret = 0;
    int an = a.size(), bn = b.size();
    for (int p = 0; p < bn - an + 1; p++) {
        bool ok = true;
        for (int k = 0; k < an; k++) {
            if (a[k] != b[k+p])
                {ok = false; break;}
        }
        if (ok) ret++;
        if (ret > 1) return ret;
    }
    return ret;
}

void findMerge() {
    memset(ind, true, sizeof ind);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j) continue;
            for (int d = min(l[i], l[j]); d >= 1; d--) {
                bool ok = true;
                for (int p = 1; p <= d; p++) {
                    if (a[j][p] != a[i][l[i]-d+p]) {
                        ok = false; break;
                    }
                }
                if (ok) {
                    mrg[i][j] = d;
                    break;
                }
            }
            if (mrg[i][j] == l[i]) ind[i] = false;
            if (mrg[i][j] == l[j]) ind[j] = false;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j || l[i] > l[j]) continue;
            for (int p = 0; p < l[j] - l[i] + 1; p++) {
                bool ok = true;
                for (int k = 1; k <= l[i]; k++) {
                    if (a[i][k] != a[j][k+p])
                        {ok = false; break;}
                }
                if (ok) {
                    ind[i] = false;
                    break;
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
        total += l[i] * ind[i];
}

string construct(vector<int> &p) {
    string s;
    for (int i = 0; i < p.size()-1; i++) {
        if (!ind[p[i]]) continue;
        int k = 1; while (i+k < p.size() && !ind[p[i+k]]) k++;
        for (int j = 1; j <= l[p[i]] - (i+k>=p.size()?0:mrg[p[i]][p[i+k]]); j++)
            s.push_back(a[p[i]][j]);
        if (i+k > n) return s;
        i += k-1;
    }
    if (ind[p.back()])
    for (int j = 1; j <= l[p.back()]; j++)
        s.push_back(a[p.back()][j]);
    return s;
}

void debug() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << mrg[i][j] << ' ';
        }
        cout << '\n';
    }
    cout << total << '\n';
}

bool check(string s) {
    for (int i = 1; i <= n; i++) {
        if (contained(str[i], s) != 1)
            return false;
    }
    return true;
}

int Resi(int N, int K, int* L, char** A, char* S) {
	n = N; l = L; a = A;

	for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= l[i]; j++) {
            str[i].push_back(a[i][j]);
        }
	}

	findMerge();

	int ans = 1e9;

	vector<int> prm;
	for (int i = 0; i < n; i++)
        prm.push_back(i+1);

    do {
        /*
        int tans = 0;
        for (int i = 1; i < n; i++) {
            tans += mrg[prm[i-1]][prm[i]];
        }
        tans = total - tans;
        if (tans > ans) {
            ans = tans;
            string s = construct(prm);
            assert(s.length() == tans);
            for (int i = 1; i <= ans; i++)
                S[i] = s[i-1];
        }
        */
        string s = construct(prm);
        if (!check(s)) continue;
        if (s.length() < ans) {
            ans = s.length();
            for (int i = 1; i <= ans; i++)
                S[i] = s[i-1];
        }
    } while (next_permutation(prm.begin(), prm.end()));

	return ans==1e9?-1:ans;

}