#include using namespace std; //#define int long long #define rep(i,n) for(int i=0;i<(n);i++) #define pb push_back #define all(v) (v).begin(),(v).end() #define fi first #define se second typedef vectorvint; typedef pairpint; typedef vectorvpint; templateinline void chmin(A &a,B b){if(a>b)a=b;} templateinline void chmax(A &a,B b){if(a&v,vector&bucket){ fill(bucket.begin(),bucket.end(),0); for(int i=0;i&v,vector&bucket){ fill(bucket.begin(),bucket.end(),0); for(int i=0;i&v,vector&sa,int mv,vector&bucket,vector&is_l){ create_begin_bucket(v,bucket); for(int i=0;i0&&is_l[sa[i]-1])sa[bucket[v[sa[i]-1]]++]=sa[i]-1; } void invert_induced_sort(vector&v,vector&sa,int mv,vector&bucket,vector&is_l){ create_end_bucket(v,bucket); for(int i=v.size()-1;i>=0;i--)if(sa[i]>0&&!is_l[sa[i]-1])sa[--bucket[v[sa[i]-1]]]=sa[i]-1; } vectorsa_is(vectorv,int mv){ if(v.size()==1)return vector(1,0); vectoris_l(v.size()); vectorbucket(mv+1); vectorsa(v.size(),-1); auto is_lms=[&](int x)->bool{return x>0&&is_l[x-1]&&!is_l[x];}; is_l[v.size()-1]=0; for(int i=v.size()-2;i>=0;i--)is_l[i]=v[i]>v[i+1]||(v[i]==v[i+1]&&is_l[i+1]); create_end_bucket(v,bucket); for(int i=0;iorder(v.size()); for(int i=0;inext_v(cur); cur=-1; int prev=-1; for(int i=0;i0&&is_lms(sa[i]+d))break; } if(diff){cur++;prev=sa[i];} next_v[order[sa[i]]]=cur; } vectorre_order(next_v.size()); for(int i=0;inext_sa=sa_is(next_v,cur); create_end_bucket(v,bucket); for(int i=0;i=0;i--)sa[--bucket[v[re_order[next_sa[i]]]]]=re_order[next_sa[i]]; induced_sort(v,sa,mv,bucket,is_l); invert_induced_sort(v,sa,mv,bucket,is_l); return sa; } void sa_is(string &s){ vectorv(s.size()+1); for(int i=0;i0)h--; for(;j+hdat; void init(vector &v){ for(N=1;N=0;i--)dat[i]=min(dat[i*2+1],dat[i*2+2]); } int get_min(int a,int b,int k,int l,int r){ if(r<=a||b<=l)return 1001001001; if(a<=l&&r<=b)return dat[k]; return min(get_min(a,b,k*2+1,l,(l+r)/2),get_min(a,b,k*2+2,(l+r)/2,r)); } int get_min(int a,int b){return get_min(a,b,0,0,N);} }; class sparse_table{ vector >st; public: void init(vectorvec){ int b; for(b=0;(1<(1<vec){init(vec);} }; public: sparse_table st; string s; vectorsa,lcp,rank; void init(string &t){ s=t; sa_is(s); construct_lcp(); st.init(lcp); } SuffixArray(string &t){init(t);} SuffixArray(){} bool contain(string &t){ int lb=0,ub=s.size(); while(ub-lb>1){ int mid=(lb+ub)/2; if(s.compare(sa[mid],t.size(),t)<0)lb=mid; else ub=mid; } return s.compare(sa[ub],t.size(),t)==0; } int get_lcp(int i,int j){ assert(i!=j); if(rank[i]>rank[j])swap(i,j); return st.get_min(rank[i],rank[j]); } int operator[](const int idx)const{ return sa[idx]; } }; int N; char buf[1000010]; string S[100000]; int acc[111111]; signed main(){ scanf("%d",&N); string s; rep(i,N){ scanf("%s",buf); S[i]=buf; s+=S[i]; acc[i+1]=acc[i]+S[i].size(); } SuffixArray sa(s); long long M,x,d; scanf("%lld%lld%lld",&M,&x,&d); long long sum=0; for(int k=1;k<=M;k++){ long long i=x/(N-1)+1; long long j=x%(N-1)+1; if(i>j)swap(i,j); else j++; sum+=min(sa.get_lcp(acc[i-1],acc[j-1]),(int)min(S[i-1].size(),S[j-1].size())); x=(x+d)%(1ll*N*(N-1)); } cout<