#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

template<class T> inline void chmax(T& a, const T& b) { if(b > a) a = b;}

constexpr int SIZE = 4;
constexpr int MAX_N = 100;
constexpr int MAX_LEN = 8;

const int dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
const int dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};

unordered_map<string, int> word_idx;

string board[SIZE];
int scores[MAX_N];
int cnt[MAX_N];
int len[MAX_N];
bool visited[SIZE][SIZE];

void dfs(int x, int y, string s = "") {
	s += board[y][x];
	if(word_idx.count(s)) ++cnt[word_idx[s]];
	if(s.size() >= MAX_LEN) return;

	visited[y][x] = true;

	for(int i = 0; i < 8; ++i) {
		const int nx = x + dx[i];
		const int ny = y + dy[i];

		if(nx < 0 || ny < 0 || nx >= SIZE || ny >= SIZE || visited[ny][nx])
			continue;

		dfs(nx, ny, s);
	}

	visited[y][x] = false;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int n;
	cin >> n;

	for(int i = 0; i < n; ++i) {
		string word;
		cin >> word >> scores[i];
		word_idx[word] = i;
		len[i] = (int)word.size();
	}

	for(int i = 0; i < SIZE; ++i) {
		cin >> board[i];
	}

	int t;
	cin >> t;

	memset(visited, false, sizeof(visited));
	for(int i = 0; i < SIZE; ++i) {
		for(int j = 0; j < SIZE; ++j) {
			dfs(j, i);
		}
	}

	vector<int> dp(t + 1, 0);
	for(int i = 0; i < n; ++i) {
		int num = cnt[i];
		for(int j = 1; num > 0; j <<= 1) {
			const int mul = min(j, num);
			const int sum_len = len[i] * mul;
			const int sum_score = scores[i] * mul;
			for(int k = t - sum_len; k >= 0; --k) {
				chmax(dp[k + sum_len], dp[k] + sum_score);
			}
			num -= mul;
		}
	}

	cout << *max_element(dp.begin(), dp.end()) << endl;

	return EXIT_SUCCESS;
}