#include <bits/stdc++.h>
using namespace std;
const long long inf = (long long)1e18;
const long long mod = (long long)1e9 + 7;
const double eps = (double)1e-9;
const double pi = acos(-1.0);
const int dx[] = {0, 0, 1, 0, -1};
const int dy[] = {0, 1, 0, -1, 0};
const int N = 1005;
const int M = 400500;
int m;
bool u[N];
char s[M];
int sz, nxt[N][14], p[N], pr[N], link[N], skip[N];
long long su[N], sum[N], val[N], prv[N][1 << 14], cur[N][1 << 14];
inline void add(int cost) {
  int v = 0, len = (int)strlen(s + 1);
  for (int i = 1; i <= len; i++) {
    int c = s[i] - 'a';
    if (nxt[v][c] == -1) {
      nxt[v][c] = ++sz;
      p[sz] = v;
      pr[sz] = c;
    }
    v = nxt[v][c];
  }
  su[v] += cost;
}
int get_nxt(int v, int c);
int get_link(int v) {
  if (link[v] != -1) return link[v];
  if (!v || !p[v]) return link[v] = 0;
  return link[v] = get_nxt(get_link(p[v]), pr[v]);
}
int get_nxt(int v, int c) {
  if (nxt[v][c] != -1) return nxt[v][c];
  if (!v) return nxt[v][c] = 0;
  return nxt[v][c] = get_nxt(get_link(v), c);
}
long long get_sum(int v) {
  if (u[v]) return sum[v];
  u[v] = 1;
  if (!v) return sum[v] = 0;
  return sum[v] = su[v] + get_sum(get_link(v));
}
int main() {
  memset(link, -1, sizeof(link));
  memset(nxt, -1, sizeof(nxt));
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    scanf("%s", s + 1);
    int cost;
    scanf("%d", &cost);
    add(cost);
  }
  for (int i = 0; i <= sz; i++) {
    link[i] = get_link(i);
    sum[i] = get_sum(i);
    for (int j = 0; j < 14; j++) nxt[i][j] = get_nxt(i, j);
  }
  scanf("%s", s);
  int n = (int)strlen(s);
  vector<int> pos;
  for (int i = 0; i < n; i++) {
    if (s[i] == '?') pos.push_back(i);
  }
  pos.push_back(n);
  for (int i = 0; i <= sz; i++) {
    for (int j = 0; j < (1 << 14); j++) {
      prv[i][j] = cur[i][j] = -inf;
    }
  }
  int v = 0;
  long long cur_val = 0;
  for (int i = 0; i < pos[0]; i++) {
    v = nxt[v][s[i] - 'a'];
    cur_val += sum[v];
  }
  prv[v][0] = cur_val;
  for (int i = 0; i + 1 < (int)pos.size(); i++) {
    for (int j = 0; j <= sz; j++) {
      int v = j;
      long long res = 0;
      for (int k = pos[i] + 1; k < pos[i + 1]; k++) {
        v = nxt[v][s[k] - 'a'];
        res += sum[v];
      }
      skip[j] = v;
      val[j] = res;
    }
    for (int mask = 0; mask < (1 << 14); mask++) {
      if (__builtin_popcount(mask) != i) continue;
      for (int j = 0; j <= sz; j++) {
        if (prv[j][mask] == -inf) continue;
        for (int let = 0; let < 14; let++) {
          if (mask >> let & 1) continue;
          int V = nxt[j][let];
          cur[skip[V]][mask | (1 << let)] = max(cur[skip[V]][mask | (1 << let)],
                                                prv[j][mask] + sum[V] + val[V]);
        }
      }
    }
    for (int j = 0; j <= sz; j++) {
      for (int k = 0; k < (1 << 14); k++) {
        swap(prv[j][k], cur[j][k]);
        cur[j][k] = -inf;
      }
    }
  }
  long long ans = -inf;
  for (int i = 0; i <= sz; i++)
    for (int j = 0; j < (1 << 14); j++) ans = max(ans, prv[i][j]);
  printf("%lld", ans);
  return 0;
}
