#ifndef LOCAL #pragma GCC optimize("O3") #endif #include using namespace std; #define sim template muu & operator<<( #define ris return *this #define R22(r) sim> typename enable_if<1 r sizeof(dud(0)),muu&>::type operator<<(c g) { sim> struct rge {c b, e;}; sim> rge range(c i, c j) {return {i, j};} sim> auto dud(c*r)->decltype(cerr << *r); sim> char dud(...); struct muu { #ifdef LOCAL stringstream a; ~muu() {cerr << a.str() << endl;} R22(<) a << boolalpha << g; ris;} R22(==) ris << range(begin(g), end(g));} sim, class b mor pair r) {ris << "(" << r.first << ", " << r.second << ")";} sim mor rge u) { a << "["; for (c i = u.b; i != u.e; ++i) *this << ", " + 2 * (i == u.b) << *i; ris << "]"; } #define qel(t) sim, class d, class...e mor t r) {ris << *(d*)&r;} qel(stack) qel(queue) qel(priority_queue) template r) { a << "("; int q = 0; apply([&](c...x){((*this << ", " + 2 * !q++ << x), ...);}, r); ris << ")"; } #else sim mor const c&){ris;} #endif }; #define imie(r...) "[" #r ": " << (r) << "] " #define arr(a, i) "[" #a imie(i) ": " << a[i] << "] " #define arr2(a, i, j) "[" #a imie(i) imie(j) ": " << a[i][j] << "] " #define range(a, b) "[[" #a ", " #b "): " << range(a, b) << "] " #define debug muu() << __FUNCTION__ << "#" << __LINE__ << ": " using ll = long long; using ld = long double; using unt = unsigned int; using pii = pair; using vpii = vector ; using ull = unsigned long long; using vi = vector; using Pii = pii; using vll = vector ; sim> void mini(c &a, const c& b) {if (a > b) a = b;} sim> void maxi(c &a, const c& b) {if (a < b) a = b;} const int A = 26, nax = 1e5 + 44; const ll llinf = 1e16; ll which[A]; char word[nax]; int p = -1; array run(string x) { if (x.size() == 1u) { array ans; fill(ans.begin(), ans.end(), 0); if (x[0] == '\?') for (int i = 0; i < A; ++i) ans[i] = which[i]; else { for (int i = 0; i < A; ++i) ans[i] = -llinf; ans[x[0] - 'A'] = which[x[0] - 'A']; } debug imie(x) imie(ans); return ans; } else { assert(x.size() % p == 0); vector out(p); for (int i = 0; i < (int) x.size(); ++i) out[i % p].push_back(x[i]); array ans; fill(ans.begin(), ans.end(), 0); for (int i = 0; i < p; ++i) { auto r = run(out[i]); for (int j = 0; j < A; ++j) ans[j] += r[j]; ans[A] += *max_element(r.begin(), r.end()); } for (int i = 0; i < A; ++i) ans[i] += x.size() * which[i]; for (auto &x : ans) maxi(x, -llinf); debug imie(x) imie(ans); return ans; } } int main() { int n, k; scanf("%d%s%d", &n, word, &k); for (int i = 0; i < A; ++i) which[i] = -1e11; for (int i = 0; i < k; ++i) { char t; int v; scanf(" %c%d", &t, &v); which[t - 'A'] = v; } for (int i = 2; i <= n; ++i) if (n % i == 0) { p = i; break; } debug imie(p); auto r = run(word); ll ans = -llinf; for (int i = 0; i <= A; ++i) maxi(ans, r[i]); printf("%lld\n", ans); }