#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 100, M = 1005, C = 14;
const long long inf = 1e15;
int K, n, c[N], to[20][M], id[N], fail[M], ch[M][26], cnt[1 << 14], tot, val[M];
long long f[20][M], g[1 << C][M], ans;
char str[N], t[M];
vector<int> pos;
void cmax(long long &x, long long y) { x = x >= y ? x : y; }
void ins(int len, int w) {
  int cur = 0;
  for (int i = 1; i <= len; ++i) {
    int fl = t[i] - 'a';
    if (!ch[cur][fl]) ch[cur][fl] = ++tot;
    cur = ch[cur][fl];
  }
  val[cur] += w;
}
void build_fail() {
  queue<int> q;
  for (int i = 0; i < C; ++i)
    if (ch[0][i]) q.push(ch[0][i]);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    val[u] += val[fail[u]];
    for (int i = 0; i < C; ++i) {
      if (ch[u][i])
        fail[ch[u][i]] = ch[fail[u]][i], q.push(ch[u][i]);
      else
        ch[u][i] = ch[fail[u]][i];
    }
  }
}
void work(int x, int l, int r) {
  for (int u = 0; u <= tot; ++u) {
    int cur = u;
    for (int i = l; i <= r; ++i)
      cur = ch[cur][str[i] - 'a'], f[x][u] += val[cur];
    to[x][u] = cur;
  }
}
int main() {
  scanf("%d", &K);
  for (int i = 1, len; i <= K; ++i) {
    scanf("%s%d", t + 1, &c[i]);
    len = strlen(t + 1);
    ins(len, c[i]);
  }
  build_fail();
  scanf("%s", str + 1);
  n = strlen(str + 1);
  for (int i = 1; i <= n; ++i)
    if (str[i] == '?') pos.push_back(i);
  if (!pos.size()) {
    work(1, 1, n);
    printf("%lld", f[1][0]);
    return 0;
  }
  int ct = 0;
  for (int i = 0; i < pos.size(); ++i)
    if (pos[i] < n && str[pos[i] + 1] != '?') {
      id[pos[i]] = ++ct;
      work(ct, pos[i] + 1, i == pos.size() - 1 ? n : pos[i + 1] - 1);
    }
  for (int i = 0; i < 1 << C; ++i)
    for (int j = 0; j <= tot; ++j) g[i][j] = -inf;
  if (pos[0] > 1) {
    work(0, 1, pos[0] - 1), g[0][to[0][0]] = f[0][0];
  } else
    g[0][0] = 0;
  for (int i = 0; i < 1 << C; ++i) cnt[i] = cnt[i >> 1] + (i & 1);
  for (int i = 0; i < 1 << C; ++i) {
    if (cnt[i] >= pos.size()) continue;
    for (int j = 0; j <= tot; ++j) {
      if (g[i][j] == -inf) continue;
      for (int x = 0; x < C; ++x) {
        if (i & (1 << x)) continue;
        int s = i ? id[pos[cnt[i] - 1]] : 0;
        if (s)
          cmax(g[i | (1 << x)][ch[to[s][j]][x]],
               g[i][j] + f[s][j] + val[ch[to[s][j]][x]]);
        else
          cmax(g[i | (1 << x)][ch[j][x]], g[i][j] + val[ch[j][x]]);
      }
    }
  }
  ans = -inf;
  for (int i = 0; i < 1 << C; ++i) {
    if (cnt[i] != pos.size()) continue;
    for (int j = 0; j <= tot; ++j) {
      if (pos.back() == n)
        cmax(ans, g[i][j]);
      else
        cmax(ans, g[i][j] + f[id[pos.back()]][j]);
    }
  }
  printf("%lld", ans);
  return 0;
}
