/*AMETHYSTS*/
#pragma comment(linker, "/STACK:1000000000")
#include <cstdio>
#include <iostream>
#include <ctime>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <set>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <bitset>
#include <deque>
#include <stack>
#include <climits>
#include <string>
#include <queue>
#include <memory.h>
#include <map>
#include <unordered_map>

#define ll long long
#define ld long double
#define pii pair <ll, ll>
#define mp make_pair

using namespace std;

const int maxn = (int)1e5 + 10;
const ll mod = (ll)1e9 + 7;
const ll inf = (ll)1e18 + 7;

struct tr {
	int go[26];
	vector<int> term;
	int lnk, tlnk, c, p;

	tr() {
		lnk = tlnk = c = p = -1;
		for (int i = 0; i < 26; i++) {
			go[i] = -1;
		}
	}
};

int n, sz = 1, q, l, r;
tr trie[20 * maxn];
string s;
ll h[maxn], ans1 = inf, ans2 = 0;

void add(string s, int ind) {
	int ver = 0;
	for (int i = 0; i < s.length(); i++) {
		if (trie[ver].go[s[i] - 'a'] != -1) {
			ver = trie[ver].go[s[i] - 'a'];
		}
		else {
			trie[ver].go[s[i] - 'a'] = sz++;
			trie[sz - 1].c = s[i] - 'a';
			trie[sz - 1].p = ver;
			ver = sz - 1;
		}
	}
	trie[ver].term.push_back(ind);
	return;
}

int go(int ver, int c);

int getlink(int ver) {
	if (trie[ver].lnk != -1) {
		return trie[ver].lnk;
	}
	else if (ver == 0 || trie[ver].p == 0) {
		return trie[ver].lnk = 0;
	}
	else {
		return trie[ver].lnk = go(getlink(trie[ver].p), trie[ver].c);
	}
}

int go(int ver, int c) {
	if (trie[ver].go[c] != -1) {
		return trie[ver].go[c];
	}
	else {
		if (ver == 0) {
			return trie[ver].go[c] = 0;
		}
		return trie[ver].go[c] = go(getlink(ver), c);
	}
}

int getplink(int ver) {
	if (ver == 0) {
		return trie[ver].tlnk = ver;
	}
	if (trie[ver].tlnk != -1) {
		return trie[ver].tlnk;
	}
	else if (trie[getlink(ver)].term.size()) {
		return trie[ver].tlnk = trie[ver].lnk;
	}
	else {
		return trie[ver].tlnk = getplink(trie[ver].lnk);
	}
}

ll getans(int ver, int l, int r) {
	ll tans = 0;
	for (int i = 0; i < trie[ver].term.size(); i++) {
		if (trie[ver].term[i] >= l && trie[ver].term[i] <= r) {
			tans += h[trie[ver].term[i]];
		}
	}
	if (getplink(ver) > 0) {
		tans += getans(trie[ver].tlnk, l, r);
	}
	return tans;
}

ll get(string s, int l, int r) {
	int ver = 0;
	ll tans = 0;
	for (int i = 0; i < s.length(); i++) {
		tans += getans(ver, l, r);
		ver = go(ver, s[i] - 'a');
	}
	tans += getans(ver, l, r);
	return tans;
}

int main() {

	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> s;
		add(s, i);
	}
	for (int i = 0; i < n; i++) {
		cin >> h[i];
	}
	cin >> q;
	for (int i = 0; i < q; i++) {
		cin >> l >> r >> s;
		ll tmp = get(s, l, r);
		ans1 = min(ans1, tmp);
		ans2 = max(ans2, tmp);
	}
	cout << ans1 << ' ' << ans2;
	return 0;
}