#include using namespace std; #define rep(i, n) for(int i = 0; i < n; i++) #define rep2(i, x, n) for(int i = x; i <= n; i++) #define rep3(i, x, n) for(int i = x; i >= n; i--) #define elif else if #define sp(x) fixed << setprecision(x) #define pb push_back #define eb emplace_back #define all(x) x.begin(), x.end() #define sz(x) (int)x.size() using ll = long long; using ld = long double; using pii = pair; using pil = pair; using pli = pair; using pll = pair; const ll MOD = 1e9+7; //const ll MOD = 998244353; const int inf = (1<<30)-1; const ll INF = (1LL<<60)-1; const ld EPS = 1e-10; template bool chmax(T &x, const T &y) {return (x < y)? (x = y, true) : false;}; template bool chmin(T &x, const T &y) {return (x > y)? (x = y, true) : false;}; struct Suffix_Array{ const string s; const int n; vector sa; Suffix_Array(const string &str) : s(str+'$'), n(sz(s)){ sa.resize(n); iota(all(sa), 0); sort(all(sa), [&](int a, int b){ return s[a] == s[b] ? a > b : s[a] < s[b]; }); vector rank(n), c(s.begin(), s.end()), cnt(n); for(int len = 1; len < n; len <<= 1){ rep(i, n){ if(i == 0 || c[sa[i-1]] != c[sa[i]]) rank[sa[i]] = i; else{ if(c[sa[i-1]+len/2] != c[sa[i]+len/2]) rank[sa[i]] = i; else rank[sa[i]] = rank[sa[i-1]]; } } iota(all(cnt), 0); copy(all(sa), c.begin()); rep(i, n){ int j = c[i]-len; if(j >= 0) sa[cnt[rank[j]]++] = j; } swap(rank, c); } } int operator [] (int i) const {return sa[i];} int size() const {return n;} }; struct Longest_Common_Prefix_Array{ const Suffix_Array sa; const int n; vector lcp, ord; Longest_Common_Prefix_Array(const Suffix_Array &sa) : sa(sa), n(sa.size()-1){ lcp.assign(n, 0), ord.assign(n+1, 0); lcp[0] = 0; rep(i, n+1) ord[sa[i]] = i; int h = 0; rep(i, n){ int j = sa[ord[i]-1]; if(h > 0) h--; while(max(i, j)+h < n && sa.s[i+h] == sa.s[j+h]) h++; lcp[ord[i]-1] = h; } } int operator [] (int i) const {return lcp[i];} }; template struct Sparse_Table{ Semigroup ope(Semigroup a, Semigroup b){ return min(a, b); } const int n; vector> st; vector lookup; Sparse_Table(const vector &table) : n(sz(table)){ st.resize(n); rep(i, n) st[i].pb(table[i]); for(int k = 0; (1<> N; string s[N]; rep(i, N) cin >> s[i]; int n = 0, pos[N]; rep(i, N) pos[i] = n, n += sz(s[i]); string S; rep(i, N) S += s[i]; Suffix_Array sa(S); int rank[n+1]; rep(i, n+1) rank[sa[i]] = i; Longest_Common_Prefix_Array lcp(sa); pii p[N]; rep(i, N) p[i] = pii(rank[pos[i]], i); sort(p, p+N); int ord[N]; rep(i, N) ord[p[i].second] = i; vector table(N-1); rep(i, N-1){ table[i] = lcp[p[i].first]; rep2(j, p[i].first+1, p[i+1].first-1) chmin(table[i], lcp[j]); } Sparse_Table st(table); int M; ll x, d; cin >> M >> x >> d; ll ans = 0; rep(i, M){ int a = x/(N-1), b = x%(N-1); if(a > b) swap(a, b); else b++; int tmp = min(sz(s[a]), sz(s[b])); a = ord[a], b = ord[b]; if(a > b) swap(a, b); chmin(tmp, st.query(a, b)); ans += tmp; x += d, x %= N*(N-1); } cout << ans << endl; }