#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000
#define long long long // for codeforces

int node[1000][26];
int type[1000][26];
int nodes = 0;

string word[100];
int score[100];

char m[6][6];
bool visited[6][6];

inline int init_node(){
  rep(i,26) node[nodes][i] = -1;
  rep(i,26) type[nodes][i] = -1;
  return nodes++;
}

void build_trie(int idx, int l, int node_id){
  if(word[idx].size() == l+1){
    type[node_id][word[idx].back()-'A'] = idx;
    return;
  }
  int c = word[idx][l] - 'A';
  // dbg(idx,l,node_id,word[idx]);
  assert(0<=c && c<26);
  if(node[node_id][c] == -1) node[node_id][c] = init_node();
  build_trie(idx, l+1, node[node_id][c]);
}

int cnt[111];

void dfs(int x, int y, int node_id, int dep){
  int c = m[x][y] - 'A';
  if(type[node_id][c]>=0) cnt[type[node_id][c]]++;

  visited[x][y] = true;
  int nid = node[node_id][c];
  if(nid>=0){
    rep(dx,-1,2) rep(dy,-1,2){
      int nx = x + dx, ny = y + dy;
      if(visited[nx][ny] || m[nx][ny]=='\0') continue;
      if(nid>=0) dfs(nx, ny, nid, dep+1);
    }
  }
  visited[x][y] = false;
}

int main(){
  int n;
  cin>>n;
  rep(i,n) cin>>word[i]>>score[i];

  init_node();
  rep(i,n) build_trie(i,0,0);

  fill(m[0], m[6], '\0');
  fill(visited[0], visited[6], false);
  rep(i,4) scanf("%s", &m[i+1][1]);

  fill(cnt, cnt+n, 0);
  rep(i,1,5)rep(j,1,5) dfs(i,j,0,1);

  int t;
  cin>>t;
  vector<int> dp(t+1, 0);
  rep(i,n){
    vector<int> nxt(dp);
    int sz = word[i].size();
    for(int j=1; sz*j<=t && j<=cnt[i]; j++){
      int c = sz*j;
      int v = score[i]*j;
      for(int k = t-c; k>=0; k--){
        nxt[k+c] = max(nxt[k+c], dp[k]+v);
      }
    }
    swap(dp, nxt);
  }

  cout << *max_element(all(dp)) << endl;

  return 0;
}