#include using namespace std; using ll=long long; using ld=double; #define FOR(i,a,b) for(ll i=a;i<(ll)b;++i) #define F(n) FOR(i,0,n) #define FF(n) FOR(j,0,n) #define aa first #define bb second #define PB push_back #define EQ(a,b) (fabs(a-b)<=(fabs(a+b)*EPS)) #define MOD ((ll)(1e9+7)) #define INF (1ll << 60) ll n; // n = p^k, size of input string ll p; string a; ll prices[255]; // prices for each letter // selected, size, offset map,ll> noBest; // cycle not selected map,ll> yesBest; // cycle selected // used for temporary copy map,ll> noBest2; map,ll> yesBest2; char cycleLetter(ll size, ll offset) { char found = '?'; for (ll i = 0; i < size; i ++) { const char curChar = a[(i*n/size + offset)%n]; if (curChar == '?') continue; else if (found == '?') found = curChar; //else if (found != curChar) return 0; else if (found != curChar) found = 0; } return found; } int main(){ ios::sync_with_stdio(0);cin.tie(0); cin >> n >> a; p = 1; for (ll i = 2; i <= n; ++ i) { if (n%i == 0) { p = i; break; } } ll alpha; cin >> alpha; F(alpha) { char c; cin >> c >> prices[c]; prices['?'] = max(prices['?'], prices[c]); } ll level = 0; for (ll size = 1; size <= n && (p != 1 || level == 0); size *= p) { level ++; for (ll offset = 0; offset < n/size; ++ offset) { // DONT SELECT if (size == 1) { // the trivial case noBest2[{size, offset}] = 0; } else { ll value = 0; for (ll i = 0; i < p; ++ i) { value += max(noBest[{size/p, i*n/size + offset}], yesBest[{size/p, i*n/size + offset}]); } noBest2[{size, offset}] = value; } // SELECT char letter = cycleLetter(size, offset); yesBest2[{size, offset}] = level * prices[letter] * size; } // keep the maps small yesBest = yesBest2; noBest = noBest2; yesBest2 = map,ll>(); noBest2 = map,ll>(); } cout << max(noBest[{n, 0}], yesBest[{n, 0}]) << endl; return 0; }