/* #pragma GCC optimize("O3,unroll-loops") */ /* #pragma GCC optimize("Ofast,unroll-loops") */ /* #pragma GCC target("avx2,popcnt") */ #include #include #include #define pb push_back #define mp make_pair #define all(a) begin(a),end(a) #define FOR(x,val,to) for(int x=(val);x pi; typedef std::vector vi; typedef std::vector vs; typedef int64_t ll; typedef uint64_t ull; #define umap unordered_map #define uset unordered_set using namespace std; using namespace __gnu_pbds; #ifdef ONLINE_JUDGE #define whatis(x) ; #endif #ifdef _WIN32 #define getchar_unlocked() _getchar_nolock() #define _CRT_DISABLE_PERFCRIT_LOCKS #endif template ostream& operator<<(ostream &os, pair P) { os<<"("< ostream& operator<<(ostream &os, map P) { for(auto const &vv: P)os<<"("< ostream& operator<<(ostream &os, set V) { os<<"[";for(auto const &vv:V)os< ostream& operator<<(ostream &os, vector V) { os<<"[";for(auto const &vv:V)os<32){str+=cur;cur=getchar_unlocked();}} template inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); } template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound template using ordered_map = tree, rb_tree_tag, tree_order_statistics_node_update>; #define N 1000001 #define int ll int cost[128]; int n; string s; int mostexp; int basepow; int deg; /* void rec(int poz, int d){ */ /* int rec(int poz, int d){ */ int rec(int poz, int d, int crdeg){ /* whatis(poz) */ /* whatis(d) */ /* whatis(crdeg) */ int ret = 0; char wh = -1; // -1 none -2 > 1 dif. // -1 none 0 bad actually. for(int i = poz;;){ /* if(s[i] == '?') */ /* continue; */ if(s[i] != '?'){ if(wh == -1) wh = s[i]; else if(wh != s[i]){ wh = 0; break; } } i += d; if(i >= n) i -= n; if(i == poz) break; } /* assert(wh != -1); */ // '?' actually. if(wh != 0){ int whcost; if(wh == -1) whcost = mostexp; else whcost = cost[wh]; /* ret = max(ret, whcost * d * (deg - crdeg + 1)); */ ret = max(ret, whcost * (n / d) * (deg - crdeg + 1)); } /* whatis("2nd") */ // first basepow. // or is it? if(d != n){ int oth = 0; int it = 0; for(int i = poz;;){ oth += rec(i, d * basepow, crdeg + 1); if(++it == basepow) break; i += d; if(i >= n) i -= n; /* if(i == poz) */ /* break; */ } ret = max(ret, oth); } /* whatis(poz) */ /* whatis(d) */ /* whatis(crdeg) */ /* whatis(ret) */ return ret; } /* int main(){ */ int32_t main(){ ios_base::sync_with_stdio(0);cin.tie(0); sc(n); FORE(i,2,n){ if(n % i == 0){ basepow = i; int nn = n; deg = 0; while(nn != 1){ nn /= basepow; ++deg; } break; } assert(0); } /* whatis(basepow) */ /* whatis(deg) */ getstr(s); int k; sc(k); FOR(x,0,k){ char c; int wh; getch(c); sc(wh); cost[c] = wh; mostexp = max(mostexp, wh); } /* cout << rec(0, 1) << '\n'; */ cout << rec(0, 1, 0) << '\n'; }