#include <bits/stdc++.h>
using namespace std;
int idx(char c) { return c - 'a'; }
const int NODE_SIZE = 1050, SIGMA_SIZE = 14;
class AhoCorasick {
 public:
  int ch[NODE_SIZE][SIGMA_SIZE];
  int fail[NODE_SIZE];
  int val[NODE_SIZE];
  int last[NODE_SIZE];
  int size;
  void init() {
    size = 1;
    memset(ch[0], 0, sizeof(ch[0]));
  }
  void insert(const string &s, int flag) {
    int n = s.size();
    int o = 0;
    for (int i = 0; i < n; i++) {
      int c = idx(s[i]);
      if (!ch[o][c]) {
        memset(ch[size], 0, sizeof(ch[size]));
        val[size] = 0;
        ch[o][c] = size++;
      }
      o = ch[o][c];
    }
    val[o] += flag;
  }
  long long calc(int j) {
    long long ans = 0;
    if (j) {
      ans += val[j];
      ans += calc(last[j]);
    }
    return ans;
  }
  void get_fail() {
    queue<int> q;
    fail[0] = 0;
    for (int c = 0; c < SIGMA_SIZE; c++) {
      int u = ch[0][c];
      if (u) fail[u] = 0, q.push(u), last[u] = 0;
    }
    while (!q.empty()) {
      int r = q.front();
      q.pop();
      for (int c = 0; c < SIGMA_SIZE; c++) {
        int u = ch[r][c];
        if (!u) {
          ch[r][c] = ch[fail[r]][c];
          continue;
        }
        q.push(u);
        int v = fail[r];
        while (v && !ch[v][c]) v = fail[v];
        fail[u] = ch[v][c];
        last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
      }
    }
  }
} ac;
long long dp[1050][1 << SIGMA_SIZE];
int nxt[1050];
long long sum[1050];
void cmax(long long &x, long long y) {
  if (x < y) x = y;
}
int bitcount(int x) { return x ? bitcount(x >> 1) + (x & 1) : 0; }
int main() {
  ios::sync_with_stdio(0);
  int k, c;
  string s;
  vector<int> pos(1, -1);
  cin >> k;
  ac.init();
  while (k--) {
    cin >> s >> c;
    ac.insert(s, c);
  }
  ac.get_fail();
  cin >> s;
  memset(dp, 0xcf, sizeof(dp));
  dp[0][0] = 0;
  for (int i = 0; i < s.size(); i++) {
    if (s[i] == '?') pos.push_back(i);
  }
  int mask_num = int(pos.size()) - 1;
  for (int m = 1; m <= mask_num; m++) {
    for (int state = 0; state < ac.size; state++) {
      sum[state] = 0;
      int o = state;
      for (int c = pos[m - 1] + 1; c < pos[m]; c++) {
        o = ac.ch[o][idx(s[c])];
        sum[state] += ac.calc(o);
      }
      nxt[state] = o;
    }
    for (int S = 0; S < 1 << SIGMA_SIZE; S++) {
      if (bitcount(S) != m - 1) continue;
      for (int state = 0; state < ac.size; state++) {
        for (int c = 0; c < SIGMA_SIZE; c++) {
          if (S & (1 << c)) continue;
          int next_state = nxt[state];
          cmax(dp[ac.ch[next_state][c]][S ^ (1 << c)],
               dp[state][S] + sum[state] + ac.calc(ac.ch[next_state][c]));
        }
      }
    }
  }
  long long ans = -1e18;
  for (int state = 0; state < ac.size; state++) {
    sum[state] = 0;
    int o = state;
    for (int c = pos.back() + 1; c < s.size(); c++) {
      o = ac.ch[o][idx(s[c])];
      sum[state] += ac.calc(o);
    }
    nxt[state] = o;
    for (int S = 0; S < 1 << SIGMA_SIZE; S++) {
      if (bitcount(S) != mask_num) continue;
      cmax(ans, dp[state][S] + sum[state]);
    }
  }
  cout << ans << endl;
  return 0;
}
