#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace atcoder; typedef long long ll; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define repr(i, n) for (int i = (int)(n) - 1; i >= 0; i--) #define repk(i, k, n) for (int i = k; i < (int)(n); i++) #define all(v) v.begin(), v.end() #define mod1 1000000007 #define mod2 998244353 #define mod3 100000007 #define vi vector #define vs vector #define vc vector #define vl vector #define vb vector #define vvi vector> #define vvc vector> #define vvl vector> #define vvb vector> #define vvvi vector>> #define vvvl vector>> #define pii pair #define pil pair #define pli pair #define pll pair #define vpii vector> #define vpll vector> #define vvpii vector>> #define vvpll vector>> template void debug(T e) { cerr << e << endl; } template void debug(vector &v) { rep(i, v.size()) { cerr << v[i] << " "; } cerr << endl; } template void debug(vector> &v) { rep(i, v.size()) { rep(j, v[i].size()) { cerr << v[i][j] << " "; } cerr << endl; } } template void debug(vector> &v) { rep(i, v.size()) { cerr << v[i].first << " " << v[i].second << endl; } } template void debug(set &st) { for (auto itr = st.begin(); itr != st.end(); itr++) { cerr << *itr << " "; } cerr << endl; } template void debug(multiset &ms) { for (auto itr = ms.begin(); itr != ms.end(); itr++) { cerr << *itr << " "; } cerr << endl; } template void debug(map &mp) { for (auto itr = mp.begin(); itr != mp.end(); itr++) { cerr << itr->first << " " << itr->second << endl; } } void debug_out() { cerr << endl; } template void debug_out(Head H, Tail... T) { cerr << H << " "; debug_out(T...); } bool done = false; void dfs(string &now_str, vector> &trie, ll v, ll rem, vector &cnt, vector &ends){ if (done) return; if (ends[v]) return; ll sum = 0; for (ll i = 0; i < 26; i++){ if (trie[v][i] != -1){ sum += cnt[trie[v][i]]; } } for (ll i = 0; i < 26; i++){ if (done) return; now_str += (char)(i + 'a'); if (trie[v][i] == -1){ done = true; cout << "Yes" << endl; cout << now_str << endl; return; } else if (sum - cnt[trie[v][i]] >= rem){ done = true; cout << "Yes" << endl; cout << now_str << endl; return; } else{ dfs(now_str, trie, trie[v][i], rem - (sum - cnt[trie[v][i]]), cnt, ends); } now_str.pop_back(); } return; } int main() { ll N, M; cin >> N >> M; vector S(N); rep(i, N) cin >> S[i]; // Trie 木を用意して、答えを求めていく vector> trie(1, vector(26, -1)); vector cnt(1, 0); vector ends(1, false); for (ll i = 0; i < N; i++){ ll len = S[i].size(); ll now = 0; for (ll j = 0; j < len; j++){ if (trie[now][(ll)(S[i][j] - 'a')] == -1){ ll len_trie = trie.size(); vector vec(26, -1); trie.push_back(vec); trie[now][(ll)(S[i][j] - 'a')] = len_trie; cnt.push_back(0); ends.push_back(false); } now = trie[now][(ll)(S[i][j] - 'a')]; cnt[now]++; } ends[now] = true; } bool pos = true; // この trie から答えを構成する方法を考えたい // 進んでいって、終端まで行ってしまったら、そこは可能性として有り得ない // そこに行く前に逃げ道が見つかれば可能性あり, DFS ll now = 0; string now_str = ""; dfs(now_str, trie, 0, M, cnt, ends); if (!done) cout << "No" << endl; }