const int maxn = 100 + 10, SZ = 26, maxs = 1<<10 + 5; int n, m; ll f[30][maxs][maxn]; vector<string> vec; class AC { public: int t[maxn][SZ], fail[maxn], val[maxn]; int tot = 0; void clear() { tot = 0; memset(t, 0, sizeof t); memset(fail, 0, sizeof fail); memset(val, 0, sizeof val); } void insert(const string &str, int idx) { int p = 0; for (auto x : str) { int c = x - 'a'; if (!t[p][c]) t[p][c] = ++tot; p = t[p][c]; } val[p] |= (1<<idx); } void build() { queue<int> que; for (int i = 0; i < SZ; i++) { if (t[0][i]) que.push(t[0][i]); } while (que.size()) { auto u = que.front(); que.pop(); for (int i = 0; i < SZ; i++) { if (t[u][i]) { fail[t[u][i]] = t[fail[u]][i]; que.push(t[u][i]); } else t[u][i] = t[fail[u]][i]; } val[u] |= val[fail[u]]; } } } ac; void init() { memset(f, -1, sizeof f); } ll dp(int i, int sta, int p) { if (i >= n) { return sta == (1<<m)-1 ? 1 : 0; } if (f[i][sta][p] != -1) return f[i][sta][p]; ll &res = f[i][sta][p]; res = 0; for (int c = 0; c < SZ; c++) { int p2 = ac.t[p][c]; res += dp(i+1, sta | ac.val[p2], p2); } return res; } void out(int i, int sta, int p, string str) { if (i >= n) { if (sta == (1<<m)-1) vec.push_back(str); return; } if (f[i][sta][p] <= 0) return; for (int c = 0; c < SZ; c++) { int p2 = ac.t[p][c]; int sta2 = sta | ac.val[p2]; char s = 'a'+c; out(i+1, sta2, p2, str+s); } } int main() { freopen("input.txt", "r", stdin); int cas = 0; while (scanf("%d%d", &n, &m) == 2 && n) { printf("Case %d: ", ++cas); ac.clear(); init(); // get data for (int i = 0; i < m; i++) { string str; cin >> str; ac.insert(str, i); } // build ac.build(); // dp ll ans = dp(0, 0, 0); printf("%lld", ans); printf(" suspects\n"); // then output solution if (ans <= 42) { vec.clear(); out(0, 0, 0, ""); sort(vec.begin(), vec.end()); for (auto s : vec) cout << s << endl; } } }