#include <bits/stdc++.h>
using namespace std;
const int sz = 1e3 + 5, alpha = 26;
const long long inf = -3e18;
char s[400005], pat[sz];
struct Corasick {
  int nd, pt, next[sz][alpha], link[sz], out_link[sz];
  long long tot[sz], score[sz];
  bool out[sz];
  void renew() {
    nd = pt = 0;
    node();
  }
  int node() {
    memset(next[nd], 0, sizeof next[nd]);
    link[nd] = out_link[nd] = out[nd] = score[nd] = tot[nd] = 0;
    return nd++;
  }
  inline int fnc(char c) { return c - 'a'; }
  void add_pat(string s, int first) {
    int u = 0;
    for (char c : s) {
      int first = fnc(c);
      if (!next[u][first]) next[u][first] = node();
      u = next[u][first];
    }
    score[u] += first;
    out[u] = 1;
    pt++;
  }
  void automate() {
    queue<int> q;
    for (q.push(0); !q.empty();) {
      int u = q.front();
      q.pop();
      for (int first = 0; first < alpha; first++) {
        int v = next[u][first], w = next[link[u]][first];
        if (!v)
          next[u][first] = w;
        else {
          int r = link[v] = u ? w : 0;
          out_link[v] = out[r] ? r : out_link[r];
          tot[v] = score[v] + tot[out_link[v]];
          q.push(v);
        }
      }
    }
  }
  inline pair<int, long long> trav(int u, int first, int second) {
    long long ans = 0;
    for (int i = first; i < second; i++) {
      char c = s[i];
      u = next[u][fnc(c)];
      ans += tot[u];
    }
    return {u, ans};
  }
} aho;
int qc;
vector<int> ques;
pair<int, long long> got[17][sz];
long long dp[1 << 14][sz];
bitset<sz> gvis[17], dvis[1 << 14];
inline pair<int, long long> lin(int z, int spot) {
  if (gvis[z][spot]) return got[z][spot];
  gvis[z][spot] = 1;
  return got[z][spot] = aho.trav(spot, ques[z] + 1, ques[z + 1]);
}
long long fnc(int msk, int spot) {
  if (!dvis[msk][spot]) {
    int z = 14 - __builtin_popcount(msk);
    auto p = lin(z, spot);
    long long ans = p.second;
    if (z < qc) {
      int u = p.first;
      long long here = inf;
      for (int i = 0; i < 14; i++) {
        if (msk & (1 << i)) {
          char c = 'a' + i;
          int j = ques[z + 1];
          s[j] = c;
          auto pp = aho.trav(u, j, j + 1);
          long long now = pp.second + fnc(msk ^ (1 << i), pp.first);
          here = max(here, now);
          s[j] = '?';
        }
      }
      ans += here;
    }
    dvis[msk][spot] = 1;
    dp[msk][spot] = ans;
  }
  return dp[msk][spot];
}
int main() {
  int n;
  scanf("%d", &n);
  aho.renew();
  for (int i = 0; i < n; i++) {
    int first;
    scanf("%s %d", pat, &first);
    aho.add_pat(pat, first);
  }
  aho.automate();
  scanf("%s", s);
  ques.push_back(-1);
  for (int i = 0;; i++) {
    if (s[i] == '?' || !s[i]) ques.push_back(i);
    if (!s[i]) break;
  }
  qc = ques.size() - 2;
  int msk = (1 << 14) - 1;
  printf("%lld\n", fnc(msk, 0));
}
