#include <bits/stdc++.h>
#pragma GCC optimize("O3")
const double PI = acos(-1);
template <class A, class B>
std::ostream& operator<<(std::ostream& st, const std::pair<A, B> p) {
  st << "(" << p.first << ", " << p.second << ")";
  return st;
}
using namespace std;
const int MAX = 1 << 10, MAXT = 400 * 1000 + 10;
char Patt[MAX], txt[MAXT];
int trie[MAX][14], siz;
int n, m;
long long cost[MAX];
void insert(int c) {
  int cur = 0;
  for (char* p = Patt; *p; p++) {
    int chr = *p - 'a';
    if (!trie[cur][chr]) trie[cur][chr] = ++siz;
    cur = trie[cur][chr];
  }
  cost[cur] += c;
}
int go_to[MAX][14], fail[MAX];
int follow(int u, int c) {
  int& ret = go_to[u][c];
  if (ret != -1) return ret;
  if (trie[u][c])
    return ret = trie[u][c];
  else if (!u)
    return ret = 0;
  else
    return ret = follow(fail[u], c);
}
void aho_corasick() {
  queue<int> q;
  memset(go_to, -1, sizeof go_to);
  for (int c = 0; c < 14; c++)
    if (trie[0][c]) {
      int u = trie[0][c];
      q.push(u);
      fail[u] = 0;
    }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int c = 0; c < 14; c++)
      if (trie[u][c]) {
        int v = trie[u][c];
        fail[v] = follow(fail[u], c);
        cost[v] += cost[fail[v]];
        q.push(v);
      }
  }
}
map<int, pair<std::pair<int, int>, long long> > mem[MAXT];
pair<std::pair<int, int>, long long> walk(int i, int u) {
  if (mem[i].count(u)) return mem[i][u];
  int j = i, v = u;
  long long res = 0;
  while (i < n && txt[i] != '?') {
    u = follow(u, txt[i] - 'a');
    res += cost[u];
    i++;
  }
  return mem[j][v] = make_pair(std::pair<int, int>(i, u), res);
}
std::vector<int> I;
long long dp[1 << 14][MAX];
bool vis[1 << 14][MAX];
long long solve(int msk, int u) {
  int cur = msk ? __builtin_popcount(msk) : 0;
  if (cur == ((int)I.size())) return walk(I.back() + 1, u).second;
  long long& ret = dp[msk][u];
  if (vis[msk][u]) return ret;
  vis[msk][u] = 1;
  int i = (cur ? I[cur - 1] : -1) + 1;
  auto aux = walk(i, u);
  u = aux.first.second;
  ret = -(1LL << 60);
  for (int c = 0; c < (14); c++)
    if (!((msk >> c) & 1)) {
      int v = follow(u, c);
      long long tmp = solve(msk ^ (1 << c), v) + aux.second + cost[v];
      ret = max(ret, tmp);
    }
  return ret;
}
int main() {
  scanf("%d", &m);
  while (m--) {
    int c;
    scanf("%s %d", Patt, &c);
    insert(c);
  }
  aho_corasick();
  scanf("%s", txt);
  n = strlen(txt);
  for (int i = 0; i < (n); i++)
    if (txt[i] == '?') I.push_back(i);
  if (I.empty()) {
    cout << walk(0, 0).second << endl;
    return 0;
  }
  cout << solve(0, 0) << endl;
  return 0;
}
