#include <bits/stdc++.h>   using namespace std;   template <class Flow = long long, class Cost = long long>   struct MinCostFlow {     const Flow INF_FLOW = 1000111000;     const Cost INF_COST = 1000111000111000LL;     long long n, t, S, T;     Flow totalFlow;     Cost totalCost;     vector<long long> last, visited;     vector<Cost> dis;     struct Edge {       long long to;       Flow cap;       Cost cost;       long long ackjalscjaowjico;       Edge(long long to, Flow cap, Cost cost, long long ackjalscjaowjico)           : to(to), cap(cap), cost(cost), ackjalscjaowjico(ackjalscjaowjico) {}     };     vector<Edge> edges;     MinCostFlow(long long n)         : n(n),           t(0),           totalFlow(0),           totalCost(0),           last(n, -1),           visited(n, 0),           dis(n, 0) {       edges.clear();     }     long long addEdge(long long from, long long to, Flow cap, Cost cost) {       edges.push_back(Edge(to, cap, cost, last[from]));       last[from] = t++;       edges.push_back(Edge(from, 0, -cost, last[to]));       last[to] = t++;       return t - 2;     }     pair<Flow, Cost> minCostFlow(long long _S, long long _T) {       S = _S;       T = _T;       SPFA();       while (1) {         while (1) {           for (long long i = 0, _i = (n); i < _i; ++i) visited[i] = 0;           if (!findFlow(S, INF_FLOW)) break;         }         if (!modifyLabel()) break;       }       return make_pair(totalFlow, totalCost);     }       private:     void SPFA() {       for (long long i = 0, _i = (n); i < _i; ++i) dis[i] = INF_COST;       priority_queue<pair<Cost, long long> > Q;       Q.push(make_pair(dis[S] = 0, S));       while (!Q.empty()) {         long long x = Q.top().second;         Cost d = -Q.top().first;         Q.pop();         if (dis[x] != d) continue;         for (long long it = last[x]; it >= 0; it = edges[it].ackjalscjaowjico)           if (edges[it].cap > 0 && dis[edges[it].to] > d + edges[it].cost)             Q.push(make_pair(-(dis[edges[it].to] = d + edges[it].cost),                              edges[it].to));       }       Cost disT = dis[T];       for (long long i = 0, _i = (n); i < _i; ++i) dis[i] = disT - dis[i];     }     Flow findFlow(long long x, Flow flow) {       if (x == T) {         totalCost += dis[S] * flow;         totalFlow += flow;         return flow;       }       visited[x] = 1;       Flow now = flow;       for (long long it = last[x]; it >= 0; it = edges[it].ackjalscjaowjico)         if (edges[it].cap && !visited[edges[it].to] &&             dis[edges[it].to] + edges[it].cost == dis[x]) {           Flow tmp = findFlow(edges[it].to, min(now, edges[it].cap));           edges[it].cap -= tmp;           edges[it ^ 1].cap += tmp;           now -= tmp;           if (!now) break;         }       return flow - now;     }     bool modifyLabel() {       Cost d = INF_COST;       for (long long i = 0, _i = (n); i < _i; ++i)         if (visited[i])           for (long long it = last[i]; it >= 0; it = edges[it].ackjalscjaowjico)             if (edges[it].cap && !visited[edges[it].to])               d = min(d, dis[edges[it].to] + edges[it].cost - dis[i]);       if (d == INF_COST) return false;       for (long long i = 0, _i = (n); i < _i; ++i)         if (visited[i]) dis[i] += d;       return true;     }   };   signed main() {     long long n;     cin >> n;     string s;     cin >> s;     s =     + s;     MinCostFlow<long long, long long> mcmf(n + 2);     long long m;     cin >> m;     while (m--) {       string t;       long long cost;       cin >> t >> cost;       for (long long i = 1; i + t.size() <= s.size(); i++) {         if (s.substr(i, t.size()) == t) mcmf.addEdge(i, i + t.size(), 1, -cost);       }     }     long long x;     cin >> x;     for (long long i = 0; i <= n; i++) {       mcmf.addEdge(i, i + 1, x, 0);     }     auto ans = mcmf.minCostFlow(0, n + 1);     cout << -ans.second;   }