#include #define left nadnlassad #define right asdaslknd #define y1 kjdajasjdsas #define nxt accepted #define prev why_would_you_call_when_you_are_high #define pb push_back #define mp make_pair #define mt make_tuple #define f first #define s second #define ll long long #define ld long double #define ull unsigned ll #define _hash pair #define pii pair #define uint unsigned int #define puu pair #define sqr(x) ((x) * 1LL * (x)) #define vec vector #define sz(v) int(v.size()) #define all(v) v.begin(), v.end() #define endl "\n" #define _bits(x) __builtin_popcountll(x) using namespace std; void rf() { #define fname "" #ifdef SONY freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #else //freopen(fname".in", "r", stdin); //freopen(fname".out", "w", stdout); #endif //SONY } const int nx[8] = {2, -2, -2, 2, 1, 1, -1, -1}; const int ny[8] = {1, 1, -1, -1, 2, -2, -2, 2}; const int Nx[4] = {0, 0, -1, 1}; const int Ny[4] = {1, -1, 0, 0}; const ll LINF = (ll) 5e18; const int INF = 1e9 + 7; const int N = 1e5 + 10; const int MAXN = 2e6 + 10; const double EPS = 1e-9, PI = 3.14159265359; int n, m; bool was[MAXN]; struct trie { int go[26]; ll cost; trie() { memset(go, -1, sizeof(go)); cost = 0; } }; trie t[MAXN]; int sz; inline void add(string s, int cost) { int cur = 0; for (auto chr : s) { int c = chr - 'a'; if (t[cur].go[c] == -1) t[cur].go[c] = ++sz; cur = t[cur].go[c]; } t[cur].cost += cost; // cout << s << " " << cost << "\n"; } string s[N], str[N]; vec query[N]; int z[MAXN], cost[N]; ll sum[MAXN]; vector > big; ll get(string s) { ll ans = 0; for (int i = 0; i < sz(s); i++) { int cur = 0; for (int j = i; j < sz(s); j++) { int c = s[j] - 'a'; if (t[cur].go[c] == -1) break; cur = t[cur].go[c]; ans += t[cur].cost; } } for (auto it : big) { string cur = it.f + "#" + s; for (int i = 1, l = 0, r = 0; i < sz(cur); i++) { z[i] = 0; if (i <= r) z[i] = min(r - i + 1, z[i - l]); while (i + z[i] < sz(cur) && cur[z[i]] == cur[i + z[i]]) z[i]++; if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1; } if (z[i] == sz(it.f)) { ans += it.s; break; } } } return ans; } void add_string(string s, int cost) { if (sz(s) <= 1000) { add(s, cost); } else { big.pb(mp(s, cost)); } } int main() { srand(time(0)); ios_base::sync_with_stdio(0), cin.tie(0); rf(); cin >> n; for (int i = 0; i < n; i++) { cin >> s[i]; } for (int i = 0; i < n; i++) { cin >> cost[i]; } cin >> m; for (int i = 1, t; i <= m; i++) { int l, r; cin >> l >> r >> str[i]; //cout << l << ' ' << r << ' ' << str << endl; if (l) query[l - 1].pb(-i); query[r].pb(i); } for (int i = 0; i < n; i++) { add_string(s[i], cost[i]); for (auto it : query[i]) { // cout << i << " " << str[abs(it)] << " " << get(str[abs(it)]) << endl; sum[abs(it)] += (it > 0 ? 1 : -1) * get(str[abs(it)]); } //return 0; } ll ans_mn = LINF; ll ans_mx = -LINF; for (int i = 1, t; i <= m; i++) { //cout << sum[i] << "\n"; ans_mn = min(ans_mn, sum[i]); ans_mx = max(ans_mx, sum[i]); } cout << ans_mn << ' ' << ans_mx; return 0; }