#include <bits/stdc++.h>
using namespace std;
const int N = 1009, MXN = 4e5 + 19, SGM = 14;
int n, ts, Cost[N], C[N][SGM], SM[N], Suf[N];
pair<int, long long> FG[N][SGM + 1];
long long dp[1 << SGM][N];
string S, A[N];
inline void Add(string s, int c) {
  int id = 0;
  for (int i = 0; i < (int)s.size(); i++) {
    if (!C[id][s[i] - 'a']) C[id][s[i] - 'a'] = ++ts;
    id = C[id][s[i] - 'a'];
  }
  SM[id] += c;
}
inline void AhoCorasick() {
  queue<int> qu;
  for (int i = 0; i < SGM; i++)
    if (C[0][i]) qu.push(C[0][i]);
  while (qu.size()) {
    int id = qu.front();
    qu.pop();
    for (int i = 0; i < SGM; i++) {
      if (C[id][i])
        Suf[C[id][i]] = C[Suf[id]][i], qu.push(C[id][i]);
      else
        C[id][i] = C[Suf[id]][i];
    }
    SM[id] += SM[Suf[id]];
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) cin >> A[i] >> Cost[i], Add(A[i], Cost[i]);
  cin >> S;
  vector<int> V = {-1};
  for (int i = 0; i < (int)S.size(); i++)
    if (S[i] == '?') V.push_back(i);
  V.push_back((int)S.size());
  AhoCorasick();
  for (int block = 0; block < (int)V.size() - 1; block++) {
    int l = V[block] + 1;
    int r = V[block + 1];
    int len = r - l;
    for (int id = 0; id <= ts; id++) {
      int nw = id;
      long long cs = 0;
      for (int i = 0; i < len; i++) nw = C[nw][S[l + i] - 'a'], cs += SM[nw];
      FG[id][block] = {nw, cs};
    }
  }
  V.erase(V.begin());
  V.erase(V.end() - 1);
  int q = (int)V.size();
  memset(dp, -63, sizeof(dp));
  dp[0][0] = 0;
  for (int mask = 1; mask < (1 << SGM); mask++)
    if (__builtin_popcount(mask) <= q) {
      for (int i = 0; i < SGM; i++)
        if (mask >> i & 1)
          for (int v = 0; v <= ts; v++) {
            int u = FG[v][__builtin_popcount(mask) - 1].first;
            long long c = FG[v][__builtin_popcount(mask) - 1].second;
            u = C[u][i];
            c += SM[u];
            dp[mask][u] = max(dp[mask][u], dp[mask - (1 << i)][v] + c);
          }
    }
  long long Mx = LLONG_MIN;
  for (int mask = 0; mask < (1 << SGM); mask++)
    if (__builtin_popcount(mask) == q)
      for (int v = 0; v <= ts; v++) {
        int u = FG[v][__builtin_popcount(mask)].first;
        long long c = FG[v][__builtin_popcount(mask)].second;
        Mx = max(Mx, dp[mask][v] + c);
      }
  printf("%lld\n", Mx);
  return 0;
}
