#include<bits/stdc++.h>
using namespace std;

#define     LL                  long long int
#define     LD                  long double
#define     ULL                 unsigned long long int

#define     pii                 pair<int, int>
#define     ump                 unordered_map
#define     mp                  make_pair
#define     mt                  make_tuple
#define     pb                  push_back
#define     ff                  first
#define     ss                  second
#define     SZ(x)               (int)x.size()
#define     all(x)              x.begin(), x.end()
#define     lb(x, y)            lower_bound(all(x), y)
#define     rep(i, begin, end)  for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))

#define     sp(x)               setprecision(x) << fixed
#define     what_is(x)          cerr << #x << " is " << x << endl;
//#define     I64                 ll

#define     PI                  acos(-1.0)
#define     inf                 1000000000
#define     mod                 1000000000 + 7
#define     EPS                 1e-12
#define     mx                  200010
#define     S_SIZE              2000010

inline void IO() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
inline int dcmp (LD x) { return x < -EPS ? -1 : (x > EPS); }

template<class T> inline int CHECK(T MASK, int i) { return (MASK >> i) & 1; }
template<class T> inline T ON(T MASK, int i) { return MASK | (T(1) << i); }
template<class T> inline T OFF(T MASK, int i) { return MASK & (~(T(1) << i)); }
template<typename T> inline int CNT(T MASK) {
    if (numeric_limits<T>::digits <= numeric_limits<unsigned int>::digits) return __builtin_popcount(MASK);
    else return __builtin_popcountll(MASK);
}
template<class T> inline int RIGHT(T MASK) { return log2(MASK & -MASK); }

int dx4[] = { 0, 0, -1, +1 }; int dy4[] = { +1, -1, 0, 0 };
int dx8[] = { 1, 1, 0, -1, -1, -1, 0, 1, 0 }; int dy8[] = { 0, 1, 1, 1, 0, -1, -1, -1, 0 };

inline void I(int& a) { scanf("%d", &a); } inline void I(LL& a) { scanf("%I64d", &a); }
inline void I(ULL& a) { scanf("%I64u", &a); } inline void I(char* a) { scanf("%s", a); }
char Iarr[S_SIZE]; inline void I(string& a) { scanf("%s", Iarr); a = Iarr; }
template<typename T, typename... Args>
void I(T& a, Args&... args) { I(a); I(args...); }

inline void OUT(int a) { printf("%d", a); } inline void OUT(LL a) { printf("%I64d", a); }
inline void OUT(const char* a) { printf("%s", a); } inline void OUT(char* a) { printf("%s", a); }
inline void OUT(bool a) { printf("%d", a); } inline void OUT(string a) { rep(it, a.begin(), a.end()) printf("%c", *it); }
inline void OUT(ULL a) { printf("%I64u", a); }
template<typename T, typename... Args>
void OUT(T a, Args... args) { OUT(a); OUT(" "); OUT(args...); }
template<typename... Args>
void O(Args... args) { OUT(args...); OUT("\n"); }

#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << endl;
	err(++it, args...);
}

// mp.reserve(1024); mp.max_load_factor(0.25);
// head

const int M = 520; // maximum number of cubes

/*... min cost flow ...*/

struct edge {int to, cap, cost, rev;};

int V;
int dist[M];
const int INF = 1e9;
int prevv[M], preve[M];
bool in_que[M];
vector<edge> g[M];

inline void add_edge(int from, int to, int cap, int cost) {
	g[from].push_back((edge){to, cap, cost, (int)g[to].size()});
	g[to].push_back((edge){from, 0, -cost, (int)g[from].size() - 1});
}

int min_cost_flow(int s, int t, int f) {
	int res = 0;

	while (f > 0) {
		fill(dist, dist + V, INF);

		queue<int> que;

		dist[s] = 0;
		que.push(s);

		while (!que.empty()) {
			int v = que.front(); que.pop();

			in_que[v] = false;

			for (int i = 0; i < (int)g[v].size(); i++) {
				edge &e = g[v][i];

				if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
					dist[e.to] = dist[v] + e.cost;
					prevv[e.to] = v;
					preve[e.to] = i;

					if (!in_que[e.to]) {
						in_que[e.to] = true;
						que.push(e.to);
					}
				}
			}
		}

		int d = f;

		for (int v = t; v != s; v = prevv[v]) {
			d = min(d, g[prevv[v]][preve[v]].cap);
		}

		f -= d;
		res += d * dist[t];

		for (int v = t; v != s; v = prevv[v]) {
			edge &e = g[prevv[v]][preve[v]];

			e.cap -= d;
			g[e.to][e.rev].cap += d;
		}
	}

	return res;
}

/*... min cost flow ...*/

int main()
{
    int n;
    I(n);
    string s;
    I(s);
    V = n + 10;
    int src = n + 5;
    int sink = n + 6;
    int m;
    I(m);
    while (m--) {
        string s1; int x;
        I(s1, x);
        for (int i = 0; i < n - SZ(s1) + 1; i++) {
            bool flag = 1;
            for (int j = 0; j < SZ(s1); j++) {
                if (s[i+j] != s1[j]) {
                    flag = 0; break;
                }
            }
            if (flag) {
                add_edge(i + 1, i + SZ(s1) + 1, 1, -x);
            }
        }
    }
    int x;
    I(x);
    for (int i = 0; i < n; i++) {
        add_edge(i + 1, i + 2, INF, 0);
    }
    add_edge(src, 1, x, 0);
    add_edge(n + 1, sink, x, 0);
    int ans = -min_cost_flow(src, sink, INF);
    O(ans);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 500 + 7;
const int OO = (int) 1e9;
int n;
int q;
string s;
int a[N];
int par_edge[N];
int best[N];
int x;

struct Edge {
        int to;
        int cap;
        int bonus;
};

vector<Edge> edges;
vector<int> g[N];

void add_edge(int a, int b, int cap, int bonus) {
        g[a].push_back((int) edges.size());
        edges.push_back({b, cap, bonus});
        g[b].push_back((int) edges.size());
        edges.push_back({a, 0, -bonus});
}

struct T {
        int x;
        int b;
};

bool operator < (T a, T b) {
        return a.x < b.x;
}

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

        cin >> n >> s >> q;
        for (int i = 1; i <= n; i++) {
                a[i] = s[i - 1];
        }
        while (q--) {
                int add;
                string t;
                cin >> t >> add;
                int sz = (int) t.size();
                for (int i = 1; i + sz - 1 <= n; i++) {
                        bool are_equal = 1;
                        for (int k = 0; k < sz; k++) {
                                if (a[i + k] != t[k]) {
                                        are_equal = 0;
                                        break;
                                }
                        }
                        if (are_equal) {
                                int j = i + sz;
                                add_edge(i, j, 1, add);
                        }
                }
        }
        for (int i = 0; i <= n; i++) {
                add_edge(i, i + 1, OO, 0);
        }
        cin >> x;
        int flow = 0, ans = 0;
        while (flow < x) {
                priority_queue<T> pq;
                pq.push({0, 0});
                for (int i = 1; i <= n + 1; i++) {
                        best[i] = -OO;
                }
                while (!pq.empty()) {
                        int a = pq.top().x;
                        int be = pq.top().b;
                        pq.pop();
                        if (be != best[a]) {
                                continue;
                        }
                        for (auto &i : g[a]) {
                                if (edges[i].cap) {
                                        int b = edges[i].to;
                                        int pos = be + edges[i].bonus;
                                        if (pos > best[b]) {
                                                best[b] = pos;
                                                par_edge[b] = i;
                                                pq.push({b, pos});
                                        }
                                }
                        }
                }
                if (best[n + 1] == -OO) {
                        break;
                }
                flow++;
                int a = n + 1;
                while (a) {
                        int i = par_edge[a];
                        edges[i].cap--;
                        edges[i ^ 1].cap++;
                        ans += edges[i].bonus;
                        a = edges[i ^ 1].to;
                }
        }
        cout << ans << "\n";
}


#include <bits/stdc++.h>

using namespace std;

const int N = 500 + 7;
const int OO = (int) 1e9;
int n;
string s;
int a[N];
int q;
int x;
int bonus[N][N];
int cap[N][N];
int best[N];
vector<int> g[N];
int par[N];

struct T {
        int x;
        int best;
};

bool operator < (T a, T b) {
        return a.best < b.best;
}

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

        cin >> n >> s >> q;
        for (int i = 1; i <= n; i++) {
                a[i] = s[i - 1];
        }
        while (q--) {
                string t;
                int add;
                cin >> t >> add;
                for (int i = 1; i + (int) t.size() - 1 <= n; i++) {
                        bool are_equal = 1;
                        for (int j = 0; j < (int) t.size(); j++) {
                                if (a[i + j] != t[j]) {
                                        are_equal = 0;
                                        break;
                                }
                        }
                        if (are_equal) {
                                cap[i][i + (int) t.size()] = 1;
                                bonus[i][i + (int) t.size()] = add;
                                bonus[i + (int) t.size()][i] = -add;
                        }
                }
        }
        for (int i = 0; i <= n; i++) {
                cap[i][i + 1] = OO;
        }
        for (int i = 0; i <= n + 1; i++) {
                for (int j = i; j <= n + 1; j++) {
                        if (cap[i][j]) {
                                g[i].push_back(j);
                                g[j].push_back(i);
                        }
                }
        }
        cin >> x;
        int flow = 0, ans = 0;
        while (flow < x) {
                best[0] = 0;
                for (int i = 1; i <= n + 1; i++) {
                        best[i] = -OO;
                }
                priority_queue<T> pq;
                pq.push({0, 0});
                while (!pq.empty()) {
                        int a = pq.top().x;
                        int b = pq.top().best;
                        pq.pop();
                        if (best[a] != b) {
                                continue;
                        }
                        for (auto &b : g[a]) {
                                if (cap[a][b] && best[a] + bonus[a][b] > best[b]) {
                                        best[b] = best[a] + bonus[a][b];
                                        par[b] = a;
                                        pq.push({b, best[b]});
                                }
                        }
                }
                if (best[n + 1] == -OO) {
                        break;
                }
                int now = n + 1;
                vector<int> path;
                while (now) {
                        path.push_back(now);
                        now = par[now];
                }
                path.push_back(0);
                reverse(path.begin(), path.end());
                for (int j = 0; j + 1 < (int) path.size(); j++) {
                        int a = path[j];
                        int b = path[j + 1];
                        cap[a][b]--;
                        cap[b][a]++;
                        ans += bonus[a][b];
                }
                flow++;
        }
        cout << ans << "\n";
}


#include <bits/stdc++.h>

using namespace std;

const int N = 500 + 7;
const int OO = (int) 1e9;
int n;
string s;
int a[N];
int q;
int x;
int bonus[N][N];
int cap[N][N];
int best[N];
bool inside[N];
vector<int> g[N];
int par[N];

struct T {
        int x;
};

bool operator < (T a, T b) {
        return best[a.x] < best[b.x];
}

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

        cin >> n >> s >> q;
        for (int i = 1; i <= n; i++) {
                a[i] = s[i - 1];
        }
        while (q--) {
                string t;
                int add;
                cin >> t >> add;
                for (int i = 1; i + (int) t.size() - 1 <= n; i++) {
                        bool are_equal = 1;
                        for (int j = 0; j < (int) t.size(); j++) {
                                if (a[i + j] != t[j]) {
                                        are_equal = 0;
                                        break;
                                }
                        }
                        if (are_equal) {
                                cap[i][i + (int) t.size()] = 1;
                                bonus[i][i + (int) t.size()] = add;
                                bonus[i + (int) t.size()][i] = -add;
                        }
                }
        }
        for (int i = 0; i <= n; i++) {
                cap[i][i + 1] = OO;
        }
        for (int i = 0; i <= n + 1; i++) {
                for (int j = i; j <= n + 1; j++) {
                        if (cap[i][j]) {
                                g[i].push_back(j);
                                g[j].push_back(i);
                        }
                }
        }
        cin >> x;
        int flow = 0, ans = 0;
        while (flow < x) {
                best[0] = 0;
                for (int i = 1; i <= n + 1; i++) {
                        best[i] = -OO;
                }
                priority_queue<T> pq;
                pq.push({0});
                while (!pq.empty()) {
                        int a = pq.top().x;
                        pq.pop();
                        inside[a] = 0;
                        for (auto &b : g[a]) {
                                if (cap[a][b] && best[a] + bonus[a][b] > best[b]) {
                                        best[b] = best[a] + bonus[a][b];
                                        if (!inside[b]) {
                                                par[b] = a;
                                                inside[b] = 1;
                                                pq.push({b});
                                        }
                                }
                        }
                }
                if (best[n + 1] == -OO) {
                        break;
                }
                int now = n + 1;
                vector<int> path;
                while (now) {
                        path.push_back(now);
                        now = par[now];
                }
                path.push_back(0);
                reverse(path.begin(), path.end());
                for (int j = 0; j + 1 < (int) path.size(); j++) {
                        int a = path[j];
                        int b = path[j + 1];
                        cap[a][b]--;
                        cap[b][a]++;
                        ans += bonus[a][b];
                }
                flow++;
        }
        cout << ans << "\n";
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const ull Seed_Pool[] = {146527, 19260817};
const ull Mod_Pool[] = {1000000009, 998244353};
struct Hash
{
    ull SEED, MOD;

    vector<ull> p, h;
    Hash() {}
    Hash(const string& s, const int& seed_index = 0, const int& mod_index = 0)
    {
        SEED = Seed_Pool[seed_index];
        MOD = Mod_Pool[mod_index];
        int n = s.length();
        p.resize(n + 1), h.resize(n + 1);
        p[0] = 1;
        for (int i = 1; i <= n; i++) p[i] = p[i - 1] * SEED % MOD;
        for (int i = 1; i <= n; i++) h[i] = (h[i - 1] * SEED % MOD + s[i - 1]) % MOD;
    }
    ull get(int l, int r) { return (h[r] - h[l] * p[r - l] % MOD + MOD) % MOD; }
    ull substr(int l, int m) { return get(l, l + m); }
};

const int N = 512;
char s[N];

const int INF = 0x3f3f3f3f;

struct Edge
{
    int from, to, cap, flow, cost;
    Edge(int u, int v, int c, int f, int w) : from(u), to(v), cap(c), flow(f), cost(w) {}
};

const int maxn = 1 << 9;
struct MCMF
{
    int n, m;
    vector<Edge> edges;
    vector<int> G[maxn];
    int inq[maxn];
    int d[maxn];
    int p[maxn];
    int a[maxn];
    void init(int n)
    {
        this->n = n;
        for (int i = 0; i < n; i++) G[i].clear();
        edges.clear();
    }
    void AddEdge(int from, int to, int cap, int cost)
    {
        edges.emplace_back(from, to, cap, 0, cost);
        edges.emplace_back(to, from, 0, 0, -cost);
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    bool BellmanFord(int s, int t, int& flow, ll& cost)
    {
        for (int i = 0; i < n; i++) d[i] = INF;
        memset(inq, 0, sizeof(inq));
        d[s] = 0;
        inq[s] = 1;
        p[s] = 0;
        a[s] = INF;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            for (int i = 0; i < G[u].size(); i++)
            {
                Edge& e = edges[G[u][i]];
                if (e.cap > e.flow && d[e.to] > d[u] + e.cost)
                {
                    d[e.to] = d[u] + e.cost;
                    p[e.to] = G[u][i];
                    a[e.to] = min(a[u], e.cap - e.flow);
                    if (!inq[e.to])
                    {
                        q.push(e.to);
                        inq[e.to] = 1;
                    }
                }
            }
        }
        if (d[t] == INF) return false;
        flow += a[t];
        cost += (ll)d[t] * (ll)a[t];
        for (int u = t; u != s; u = edges[p[u]].from)
        {
            edges[p[u]].flow += a[t];
            edges[p[u] ^ 1].flow -= a[t];
        }
        return true;
    }
    int MincostMaxflow(int s, int t, ll& cost)
    {
        int flow = 0;
        cost = 0;
        while (BellmanFord(s, t, flow, cost))
            ;
        return flow;
    }
} gao;

int main()
{
    int n;
    scanf("%d", &n);
    scanf("%s", s);
    Hash h(s);
    int m;
    scanf("%d", &m);
    gao.init(n + 3);
    int S = n + 1, T = n + 2;
    for (int i = 0, w; i < m; i++)
    {
        scanf("%s%d", s, &w);
        Hash hh(s);
        int len = strlen(s);
        ull t = hh.get(0, len);
        for (int i = 0; i + len - 1 < n; i++)
            if (h.substr(i, len) == t)
                gao.AddEdge(i, i + len, 1, -w);
    }
    int x;
    scanf("%d", &x);
    gao.AddEdge(S, 0, x, 0);
    gao.AddEdge(n, T, x, 0);
    for (int i = 0; i < n; i++) gao.AddEdge(i, i + 1, x, 0);
    ll cost;
    assert(gao.MincostMaxflow(S, T, cost) == x);
    printf("%lld\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const ull Seed_Pool[] = {146527, 19260817};
const ull Mod_Pool[] = {1000000009, 998244353};
struct Hash
{
    ull SEED, MOD;

    vector<ull> p, h;
    Hash() {}
    Hash(const string& s, const int& seed_index = 0, const int& mod_index = 0)
    {
        SEED = Seed_Pool[seed_index];
        MOD = Mod_Pool[mod_index];
        int n = s.length();
        p.resize(n + 1), h.resize(n + 1);
        p[0] = 1;
        for (int i = 1; i <= n; i++) p[i] = p[i - 1] * SEED % MOD;
        for (int i = 1; i <= n; i++) h[i] = (h[i - 1] * SEED % MOD + s[i - 1]) % MOD;
    }
    ull get(int l, int r) { return (h[r] - h[l] * p[r - l] % MOD + MOD) % MOD; }
    ull substr(int l, int m) { return get(l, l + m); }
};

const int N = 512;
char s[N];

const int INF = 0x3f3f3f3f;

struct Edge
{
    int from, to, cap, flow, cost;
    Edge(int u, int v, int c, int f, int w) : from(u), to(v), cap(c), flow(f), cost(w) {}
};

const int maxn = 1 << 9;
struct MCMF
{
    int n, m;
    vector<Edge> edges;
    vector<int> G[maxn];
    int inq[maxn];
    int d[maxn];
    int p[maxn];
    int a[maxn];
    void init(int n)
    {
        this->n = n;
        for (int i = 0; i < n; i++) G[i].clear();
        edges.clear();
    }
    void AddEdge(int from, int to, int cap, int cost)
    {
        edges.emplace_back(from, to, cap, 0, cost);
        edges.emplace_back(to, from, 0, 0, -cost);
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    bool BellmanFord(int s, int t, int& flow, ll& cost)
    {
        for (int i = 0; i < n; i++) d[i] = INF;
        memset(inq, 0, sizeof(inq));
        d[s] = 0;
        inq[s] = 1;
        p[s] = 0;
        a[s] = INF;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            for (int i = 0; i < G[u].size(); i++)
            {
                Edge& e = edges[G[u][i]];
                if (e.cap > e.flow && d[e.to] > d[u] + e.cost)
                {
                    d[e.to] = d[u] + e.cost;
                    p[e.to] = G[u][i];
                    a[e.to] = min(a[u], e.cap - e.flow);
                    if (!inq[e.to])
                    {
                        q.push(e.to);
                        inq[e.to] = 1;
                    }
                }
            }
        }
        if (d[t] == INF) return false;
        flow += a[t];
        cost += (ll)d[t] * (ll)a[t];
        for (int u = t; u != s; u = edges[p[u]].from)
        {
            edges[p[u]].flow += a[t];
            edges[p[u] ^ 1].flow -= a[t];
        }
        return true;
    }
    int MincostMaxflow(int s, int t, ll& cost)
    {
        int flow = 0;
        cost = 0;
        while (BellmanFord(s, t, flow, cost))
            ;
        return flow;
    }
} gao;

int main()
{
    int n;
    scanf("%d", &n);
    scanf("%s", s);
    Hash h(s);
    int m;
    scanf("%d", &m);
    gao.init(n + 1);
    for (int i = 0, w; i < m; i++)
    {
        scanf("%s%d", s, &w);
        Hash hh(s);
        int len = strlen(s);
        ull t = hh.get(0, len);
        for (int i = 0; i + len - 1 < n; i++)
            if (h.substr(i, len) == t)
                gao.AddEdge(i, i + len, 1, -w);
    }
    int x;
    scanf("%d", &x);
    for (int i = 0; i < n; i++) gao.AddEdge(i, i + 1, x, 0);
    ll cost;
    gao.MincostMaxflow(0, n, cost);
    printf("%lld\n", -cost);
    return 0;
}


#include "bits/stdc++.h"
#define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define all(V) (V).begin(), (V).end()
using namespace std;
typedef long long ll;
struct Edge{
    int u, v;
    long long cap, cost;

    Edge(int _u, int _v, long long _cap, long long _cost){
        u = _u; v = _v; cap = _cap; cost = _cost;
    }
};

struct MinCostFlow{
    int n, s, t;
    long long flow, cost;
    vector<vector<int> > graph;
    vector<Edge> e;
    vector<long long> dist;
    vector<int> parent;

    MinCostFlow(int _n){
        // 0-based indexing
        n = _n;
        graph.assign(n, vector<int> ());
    }

    void addEdge(int u, int v, long long cap, long long cost, bool directed = true){
        graph[u].push_back(e.size());
        e.push_back(Edge(u, v, cap, cost));

        graph[v].push_back(e.size());
        e.push_back(Edge(v, u, 0, -cost));

        if(!directed)
            addEdge(v, u, cap, cost, true);
    }

    pair<long long, long long> getMinCostFlow(int _s, int _t){
        s = _s; t = _t;
        flow = 0, cost = 0;

        while(SPFA()){
            flow += sendFlow(t, 1LL<<62);
        }

        return make_pair(flow, cost);
    }

    // not sure about negative cycle
    bool SPFA(){
        parent.assign(n, -1);
        dist.assign(n, 1LL<<62);        dist[s] = 0;
        vector<int> queuetime(n, 0);    queuetime[s] = 1;
        vector<bool> inqueue(n, 0);     inqueue[s] = true;
        queue<int> q;                   q.push(s);
        bool negativecycle = false;

        while(!q.empty() && !negativecycle){
            int u = q.front(); q.pop(); inqueue[u] = false;

            for(int i = 0; i < graph[u].size(); i++){
                int eIdx = graph[u][i];
                int v = e[eIdx].v, w = e[eIdx].cost, cap = e[eIdx].cap;

                if(dist[u] + w < dist[v] && cap > 0){
                    dist[v] = dist[u] + w;
                    parent[v] = eIdx;

                    if(!inqueue[v]){
                        q.push(v);
                        queuetime[v]++;
                        inqueue[v] = true;

                        if(queuetime[v] == n+2){
                            negativecycle = true;
                            break;
                        }
                    }
                }
            }
        }

        return dist[t] != (1LL<<62);
    }

    long long sendFlow(int v, long long curFlow){
        if(parent[v] == -1)
            return curFlow;
        int eIdx = parent[v];
        int u = e[eIdx].u, w = e[eIdx].cost;

        long long f = sendFlow(u, min(curFlow, e[eIdx].cap));

        cost += f*w;
        e[eIdx].cap -= f;
        e[eIdx^1].cap += f;

        return f;
    }
};
int main() {fio;
	int n;
	cin >> n;
	string s;
	cin >> s;
	MinCostFlow mcmf(n + 2);
	int m;
	cin >> m;
	int src = n + 1, snk = n;
	for(int i = 0; i < n; i++) {
		mcmf.addEdge(i, i + 1, 1e9, 0);
	}
	for(int i = 0; i < m; i++) {
		int p;
		string t;
		cin >> t >> p;
		for(int j = 0; j + t.size() - 1 < s.size(); j++) {
			if(s.substr(j, t.size()) == t) {
				mcmf.addEdge(j, j + t.size(), 1, -p);
			}
		}
	}
	int x;
	cin >> x;
	mcmf.addEdge(src, 0, x, 0);
	cout << -mcmf.getMinCostFlow(src, snk).second;
    return 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
//#include <atcoder/all>

#define F first
#define S second
#define int long long
#define ll long long
//#define int  unsigned long long
#define pb push_back
//#define double long double

using namespace std;
using namespace __gnu_pbds;
//using namespace atcoder;

typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 1001000;
const int K = 20;
const int mod = 998244353;
template <typename T, typename C>
class mcmf {
  public:
  static constexpr T eps = (T) 1e-9;
  struct edge {
    int from;
    int to;
    T c;
    T f;
    C cost;
  };
  vector< vector<int> > g;
  vector<edge> edges;
  vector<C> d;
  vector<int> q;
  vector<bool> in_queue;
  vector<int> pe;
  int n;
  int st, fin;
  T flow;
  C cost;
  mcmf(int _n, int _st, int _fin) : n(_n), st(_st), fin(_fin) {
    assert(0 <= st && st < n && 0 <= fin && fin < n && st != fin);
    g.resize(n);
    d.resize(n);
    in_queue.resize(n);
    pe.resize(n);
    flow = 0;
    cost = 0;
  }
  void clear_flow() {
    for (const edge &e : edges) {
      e.f = 0;
    }
    flow = 0;
  }

  void add(int from, int to, T forward_cap, T backward_cap, C cost) {
    assert(0 <= from && from < n && 0 <= to && to < n);
    g[from].push_back((int) edges.size());
    edges.push_back({from, to, forward_cap, 0, cost});
    g[to].push_back((int) edges.size());
    edges.push_back({to, from, backward_cap, 0, -cost});
  }
  bool expath() {
    fill(d.begin(), d.end(), numeric_limits<C>::max());
    q.clear();
    q.push_back(st);
    d[st] = 0;
    in_queue[st] = true;
    int beg = 0;
    bool found = false;
    while (beg < (int) q.size()) {
      int i = q[beg++];
      if (i == fin) {
        found = true;
      }
      in_queue[i] = false;
      for (int id : g[i]) {
        const edge &e = edges[id];
        if (e.c - e.f > eps && d[i] + e.cost < d[e.to]) {
          d[e.to] = d[i] + e.cost;
          pe[e.to] = id;
          if (!in_queue[e.to]) {
            q.push_back(e.to);
            in_queue[e.to] = true;
          }
        }
      }
    }
    if (found) {
      T push = numeric_limits<T>::max();
      int v = fin;
      while (v != st) {
        const edge &e = edges[pe[v]];
        push = min(push, e.c - e.f);
        v = e.from;
      }
      v = fin;
      while (v != st) {
        edge &e = edges[pe[v]];
        e.f += push;
        edge &back = edges[pe[v] ^ 1];
        back.f -= push;
        v = e.from;
      }
      flow += push;
      cost += push * d[fin];
    }
    return found;
  }

  pair<T, C> max_flow_min_cost() {
    while (expath()) {
    }
    return make_pair(flow, cost);
  }
};
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    string s;
    cin >> s;
    int m;
    cin >> m;
    mcmf <int,int> fg(n + 2, 0, n + 1);
    for (int i = 0; i < m; i++){
        string t;
        cin >> t;
        int x;
        cin >> x;
        for (int j = 0; j < n - (int)t.size() + 1; j++){
            if (s.substr(j, (int)t.size()) == t){
                fg.add(j + 1, j + t.length(), 1, 0, -x);
            }
        }
    }
    int x;
    cin >> x;
    for (int i = 0; i <= n; i++){
        fg.add(i, i + 1, x, 0, 0);
    }
    auto y = fg.max_flow_min_cost();
    cout << -y.S << endl;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
//#include <atcoder/all>

#define F first
#define S second
#define int long long
#define ll long long
//#define int  unsigned long long
#define pb push_back
//#define double long double

using namespace std;
using namespace __gnu_pbds;
//using namespace atcoder;

typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 1001000;
const int K = 20;
const int mod = 998244353;
template <typename T, typename C>
class mcmf {
  public:
  static constexpr T eps = (T) 1e-9;
  struct edge {
    int from;
    int to;
    T c;
    T f;
    C cost;
  };
  vector< vector<int> > g;
  vector<edge> edges;
  vector<C> d;
  vector<int> q;
  vector<bool> in_queue;
  vector<int> pe;
  int n;
  int st, fin;
  T flow;
  C cost;
  mcmf(int _n, int _st, int _fin) : n(_n), st(_st), fin(_fin) {
    assert(0 <= st && st < n && 0 <= fin && fin < n && st != fin);
    g.resize(n);
    d.resize(n);
    in_queue.resize(n);
    pe.resize(n);
    flow = 0;
    cost = 0;
  }
  void clear_flow() {
    for (const edge &e : edges) {
      e.f = 0;
    }
    flow = 0;
  }

  void add(int from, int to, T forward_cap, T backward_cap, C cost) {
    assert(0 <= from && from < n && 0 <= to && to < n);
    g[from].push_back((int) edges.size());
    edges.push_back({from, to, forward_cap, 0, cost});
    g[to].push_back((int) edges.size());
    edges.push_back({to, from, backward_cap, 0, -cost});
  }
  bool expath() {
    fill(d.begin(), d.end(), numeric_limits<C>::max());
    q.clear();
    q.push_back(st);
    d[st] = 0;
    in_queue[st] = true;
    int beg = 0;
    bool found = false;
    while (beg < (int) q.size()) {
      int i = q[beg++];
      if (i == fin) {
        found = true;
      }
      in_queue[i] = false;
      for (int id : g[i]) {
        const edge &e = edges[id];
        if (e.c - e.f > eps && d[i] + e.cost < d[e.to]) {
          d[e.to] = d[i] + e.cost;
          pe[e.to] = id;
          if (!in_queue[e.to]) {
            q.push_back(e.to);
            in_queue[e.to] = true;
          }
        }
      }
    }
    if (found) {
      T push = numeric_limits<T>::max();
      int v = fin;
      while (v != st) {
        const edge &e = edges[pe[v]];
        push = min(push, e.c - e.f);
        v = e.from;
      }
      v = fin;
      while (v != st) {
        edge &e = edges[pe[v]];
        e.f += push;
        edge &back = edges[pe[v] ^ 1];
        back.f -= push;
        v = e.from;
      }
      flow += push;
      cost += push * d[fin];
    }
    return found;
  }

  pair<T, C> max_flow_min_cost() {
    while (expath()) {
    }
    return make_pair(flow, cost);
  }
};
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    string s;
    cin >> s;
    int m;
    cin >> m;
    mcmf <int,int> fg(n + 3, 0, n + 2);
    for (int i = 0; i < m; i++){
        string t;
        cin >> t;
        int x;
        cin >> x;
        for (int j = 0; j < n - (int)t.size() + 1; j++){
            if (s.substr(j, (int)t.size()) == t){
                fg.add(j + 1, j + t.length() + 1, 1, 0, -x);
            }
        }
    }
    int x;
    cin >> x;
    for (int i = 0; i <= n + 1; i++){
        fg.add(i, i + 1, x, 0, 0);
    }
    auto y = fg.max_flow_min_cost();
    cout << -y.S << endl;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
 #define int long long

#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define endl '\n'
#define fi first
#define se second

using namespace __gnu_pbds;
using namespace std;
const int mod=1e9+7;
 // const int mod=998244353;
 // const int mod=1e9+9;
const int INF=4e18+10;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define read(n) int n; cin>>n;
#define readv(x, n) vector<int> x(n); for(auto &i:x) cin>>i;
int multiply(int a, int b, int in_mod){return (a*b)%in_mod;}
int mult_identity(int a){return 1;}

auto power(auto a, int b, int in_mod)
{
    auto prod=mult_identity(a);
    auto mult=a%in_mod;
    while(b!=0)
    {
        if(b%2)
        {
            prod=multiply(prod,mult, in_mod);

        }
        mult=multiply(mult, mult,in_mod);
        b/=2;
    }
    return prod;
}
int mod_inv(int q, int in_mod)
{

    return power(q, in_mod-2,in_mod);
}

#define trie teraera
struct Trie
{
    int next[26];
    // char pch;
    // int p;
    // int go[26];
    // int get_link;
    int index;
    bool leaf;
    Trie(int _p =-1 , char _pch = 'a'-1)
    {
        // p=_p;
        // pch=_pch;
        fill_n(next, 26, -1);
        // fill_n(go, 26, -1);
        // get_link=-1;
        leaf=false;
        index=-1;
    }
};

vector<Trie>trie(1);
void add_string(string s, int index)
{
    int start=0;
    for(int i=0;i<s.size();i++)
    {
        if(trie[start].next[s[i]-'a']==-1)
        {
            trie[start].next[s[i]-'a']=trie.size();
            trie.emplace_back(Trie(start, s[i]));
        }
        start=trie[start].next[s[i]-'a'];
    }
    trie[start].leaf=true;
    trie[start].index=index;
}

// int go(int node, char ch);
// int get_link(int node)
// {
//     if(trie[node].get_link==-1)
//     {
//         if(node==0 || trie[node].p==0)
//             trie[node].get_link=0;
//         else
//             trie[node].get_link=go(trie[trie[node].p].get_link, trie[node].pch);

//     }
//     return trie[node].get_link;
// }

// int go(int node, char ch)
// {
//     int c=ch-'a'
//     if(trie[node].go[c]==-1)
//     {
//         if(trie[node].next[c]!=-1)
//             trie[node].go[c]=trie[node].next[c];
//         else
//             trie[node].go[c]=v==0?0:go(get_link(node),ch);
//     }
//     return trie[node].go[c];
// }

// int n_leaves(int node)
// {
//     if(trie[node].leaf_counts==-1)
//     {

//         if(node==0)
//             trie[node].leaf_counts=0;

//         else
//         {
//             if(trie[get_link(node)].leaf)
//                 trie[node].leaf_counts=get_link(node);

//         }
//     }
//     return trie[node].leaf;
// }

const int MAXN = 1000+10;
vector<vector<pair<int, int>>> adj(MAXN);
vector<vector<vector<int> >> capacity(MAXN, vector<vector<int >> (MAXN, vector<int>(1)));
vector<vector<vector<int> > > cost(MAXN, vector<vector<int>  > (MAXN, vector<int>(1)));

vector<pair<int, int> > real_parent(MAXN, {-1, -1});

int n,m , q;

void spfa(int s, vector<int> &d, vector<pair<int, int> >&p)
{
    queue<int> q;
    d[s]=0;
    q.push(s);
    while(!q.empty())
    {
        auto top = q.front();
        q.pop();
        for(auto v:adj[top])
        {
            if(capacity[top][v.fi][v.se]>0 && d[v.fi]>d[top]+cost[top][v.fi][v.se])
            {
                d[v.fi]=d[top]+cost[top][v.fi][v.se];
                q.push(v.fi);
                p[v.fi]={top, v.se};
            }
        }
    }

}

auto max_flow(int s, int t, int K)
{
    int mn_cost = 0;
    int mx_flow=0;
    while(true)
    {
        if(K==0)
            break;
        vector<int> d(n+m+2, INF);
        vector<pair<int, int> >  p(n+m+2, {-1,-1});
        spfa(s,d, p);
        if(d[t]==INF)
            break;
        int end=t;
        int flow=INF;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            flow=min(flow, capacity[p[end].fi][end][p[end].se]);
            end=p[end].fi;
        }
        if(flow==INF)
            break;
        flow=min(flow,K);

        K-=flow;

        mn_cost+=d[t]*flow;

        mx_flow+=flow;
        end=t;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            capacity[p[end].fi][end][p[end].se]-=flow;
            capacity[end][p[end].fi][p[end].se]+=flow;

            end=p[end].fi;
        }

    }
    return make_pair(mx_flow,mn_cost);
}

void solve()
{

    // for(auto &i:adj)
    // {
    //     i.clear();
    // }
    // for(auto &i:cost)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    // for(auto &i:capacity)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    cin>>n;

    string s;
    cin>>s;

    cin>>m;

    for(int i=0;i<m;i++)
    {
        string p;
        cin>>p;
        int val;
        cin>>val;
        int len =p.size();
        for(int l=0;l+len-1<n ;l++)
        {
            int r= l+len-1;
            bool flag=true;
            for(int j =l ;j<=r;j++)
            {
                if(s[j]!=p[j-l])
                {
                    flag=false;
                }
            }
            if(flag)
            {
                adj[l+1].pb({r+2,0});
                adj[r+2].pb({l+1,0});
                cost[l+1][r+2][0]=-val;
                cost[r+2][l+1][0]=+val;
                capacity[l+1][r+2][0]=1;
            }
        }
    }

    for(int i=1;i<=n+1;i++)
    {
        adj[i-1].pb({i,0});
        adj[i].pb({i-1,0});
        cost[i-1][i][0]=0;
        cost[i][i-1][0]=0;
        capacity[i-1][i][0]=INF;

    }

    // for(int i=1;i<=m;i++)
    // {

    //     int second =i;

    //     adj[n+second].pb({n+m+1, 0});
    //     adj[n+m+1].pb({n+second, 0});

    //     capacity[n+second][n+m+1][0] = w;

    //     adj[u].pb({n+second,0});
    //     adj[n+second].pb({u,0});
    //     capacity[u][n+second][0]=INF;

    //     adj[v].pb({n+second,0});
    //     adj[n+second].pb({v,0});
    //     capacity[v][n+second][0]=INF;

    // }

    // for(int j=1;j<=n;j++)
    // {
    //     adj[n+j].pb({n+n+1,0});
    //     adj[n+n+1].pb({n+j, 0});
    //     cost[n+j][n+n+1][0]=0;
    //     cost[n+n+1][n+j][0]=0;
    //     capacity[n+j][n+n+1][0]=1;

    // }
    int x;
    cin>>x;
    auto ans=max_flow(0, n+1, x);
    // cout<<ans.fi<<" "<<ans.se<<endl;
    cout<<-ans.se<<endl;

}
signed main()

{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
        freopen ("INPUT.txt" , "r" , stdin);
        freopen ("OUTPUT.txt" , "w" , stdout);
    }
    #endif
    auto clk=clock();
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    // -------------------------------------Code starts here---------------------------------------------------------------------

    int t=1;
    // cin>>t;
    for(int test=1;test<=t;test++)
    {
        // cout<<"Case #"<<test<<": ";
        // cout<<endl;
        solve();
        // cout<<endl;

    }

    // -------------------------------------Code ends here------------------------------------------------------------------

    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "Time: " << ((double)clk)/CLOCKS_PER_SEC << "\n";
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
 #define int long long

#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define endl '\n'
#define fi first
#define se second

using namespace __gnu_pbds;
using namespace std;
const int mod=1e9+7;
 // const int mod=998244353;
 // const int mod=1e9+9;
const int INF=4e18+10;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define read(n) int n; cin>>n;
#define readv(x, n) vector<int> x(n); for(auto &i:x) cin>>i;
int multiply(int a, int b, int in_mod){return (a*b)%in_mod;}
int mult_identity(int a){return 1;}

auto power(auto a, int b, int in_mod)
{
    auto prod=mult_identity(a);
    auto mult=a%in_mod;
    while(b!=0)
    {
        if(b%2)
        {
            prod=multiply(prod,mult, in_mod);

        }
        mult=multiply(mult, mult,in_mod);
        b/=2;
    }
    return prod;
}
int mod_inv(int q, int in_mod)
{

    return power(q, in_mod-2,in_mod);
}

#define trie teraera
struct Trie
{
    int next[26];
    // char pch;
    // int p;
    // int go[26];
    // int get_link;
    int index;
    bool leaf;
    Trie(int _p =-1 , char _pch = 'a'-1)
    {
        // p=_p;
        // pch=_pch;
        fill_n(next, 26, -1);
        // fill_n(go, 26, -1);
        // get_link=-1;
        leaf=false;
        index=-1;
    }
};

vector<Trie>trie(1);
void add_string(string s, int index)
{
    int start=0;
    for(int i=0;i<s.size();i++)
    {
        if(trie[start].next[s[i]-'a']==-1)
        {
            trie[start].next[s[i]-'a']=trie.size();
            trie.emplace_back(Trie(start, s[i]));
        }
        start=trie[start].next[s[i]-'a'];
    }
    trie[start].leaf=true;
    trie[start].index=index;
}

// int go(int node, char ch);
// int get_link(int node)
// {
//     if(trie[node].get_link==-1)
//     {
//         if(node==0 || trie[node].p==0)
//             trie[node].get_link=0;
//         else
//             trie[node].get_link=go(trie[trie[node].p].get_link, trie[node].pch);

//     }
//     return trie[node].get_link;
// }

// int go(int node, char ch)
// {
//     int c=ch-'a'
//     if(trie[node].go[c]==-1)
//     {
//         if(trie[node].next[c]!=-1)
//             trie[node].go[c]=trie[node].next[c];
//         else
//             trie[node].go[c]=v==0?0:go(get_link(node),ch);
//     }
//     return trie[node].go[c];
// }

// int n_leaves(int node)
// {
//     if(trie[node].leaf_counts==-1)
//     {

//         if(node==0)
//             trie[node].leaf_counts=0;

//         else
//         {
//             if(trie[get_link(node)].leaf)
//                 trie[node].leaf_counts=get_link(node);

//         }
//     }
//     return trie[node].leaf;
// }

const int MAXN = 1000+10;
vector<vector<pair<int, int>>> adj(MAXN);
vector<vector<vector<int> >> capacity(MAXN, vector<vector<int >> (MAXN, vector<int>(2)));
vector<vector<vector<int> > > cost(MAXN, vector<vector<int>  > (MAXN, vector<int>(2)));

vector<pair<int, int> > real_parent(MAXN, {-1, -1});

int n,m , q;

void spfa(int s, vector<int> &d, vector<pair<int, int> >&p)
{
    queue<int> q;
    d[s]=0;
    q.push(s);
    while(!q.empty())
    {
        auto top = q.front();
        q.pop();
        for(auto v:adj[top])
        {
            if(capacity[top][v.fi][v.se]>0 && d[v.fi]>d[top]+cost[top][v.fi][v.se])
            {
                d[v.fi]=d[top]+cost[top][v.fi][v.se];
                q.push(v.fi);
                p[v.fi]={top, v.se};
            }
        }
    }

}

auto max_flow(int s, int t, int K)
{
    int mn_cost = 0;
    int mx_flow=0;
    while(true)
    {
        if(K==0)
            break;
        vector<int> d(n+m+2, INF);
        vector<pair<int, int> >  p(n+m+2, {-1,-1});
        spfa(s,d, p);
        if(d[t]==INF)
            break;
        int end=t;
        int flow=INF;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            flow=min(flow, capacity[p[end].fi][end][p[end].se]);
            end=p[end].fi;
        }
        if(flow==INF)
            break;
        flow=min(flow,K);

        K-=flow;

        mn_cost+=d[t]*flow;

        mx_flow+=flow;
        end=t;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            capacity[p[end].fi][end][p[end].se]-=flow;
            capacity[end][p[end].fi][p[end].se]+=flow;

            end=p[end].fi;
        }

    }
    return make_pair(mx_flow,mn_cost);
}

void solve()
{

    // for(auto &i:adj)
    // {
    //     i.clear();
    // }
    // for(auto &i:cost)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    // for(auto &i:capacity)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    cin>>n;

    string s;
    cin>>s;

    cin>>m;

    for(int i=0;i<m;i++)
    {
        string p;
        cin>>p;
        int val;
        cin>>val;
        int len =p.size();
        for(int l=0;l+len-1<n ;l++)
        {
            int r= l+len-1;
            bool flag=true;
            for(int j =l ;j<=r;j++)
            {
                if(s[j]!=p[j-l])
                {
                    flag=false;
                }
            }
            if(flag)
            {
                adj[l+1].pb({r+2,0});
                adj[r+2].pb({l+1,0});
                cost[l+1][r+2][0]=-val;
                cost[r+2][l+1][0]=+val;
                capacity[l+1][r+2][0]=1;
            }
        }
    }

    for(int i=1;i<=n+1;i++)
    {
        adj[i-1].pb({i,1});
        adj[i].pb({i-1,1});
        capacity[i-1][i][1]=INF;

    }

    // for(int i=1;i<=m;i++)
    // {

    //     int second =i;

    //     adj[n+second].pb({n+m+1, 0});
    //     adj[n+m+1].pb({n+second, 0});

    //     capacity[n+second][n+m+1][0] = w;

    //     adj[u].pb({n+second,0});
    //     adj[n+second].pb({u,0});
    //     capacity[u][n+second][0]=INF;

    //     adj[v].pb({n+second,0});
    //     adj[n+second].pb({v,0});
    //     capacity[v][n+second][0]=INF;

    // }

    // for(int j=1;j<=n;j++)
    // {
    //     adj[n+j].pb({n+n+1,0});
    //     adj[n+n+1].pb({n+j, 0});
    //     cost[n+j][n+n+1][0]=0;
    //     cost[n+n+1][n+j][0]=0;
    //     capacity[n+j][n+n+1][0]=1;

    // }
    int x;
    cin>>x;
    auto ans=max_flow(0, n+1, x);
    // cout<<ans.fi<<" "<<ans.se<<endl;
    cout<<-ans.se<<endl;

}
signed main()

{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
        freopen ("INPUT.txt" , "r" , stdin);
        freopen ("OUTPUT.txt" , "w" , stdout);
    }
    #endif
    auto clk=clock();
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    // -------------------------------------Code starts here---------------------------------------------------------------------

    int t=1;
    // cin>>t;
    for(int test=1;test<=t;test++)
    {
        // cout<<"Case #"<<test<<": ";
        // cout<<endl;
        solve();
        // cout<<endl;

    }

    // -------------------------------------Code ends here------------------------------------------------------------------

    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "Time: " << ((double)clk)/CLOCKS_PER_SEC << "\n";
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
 #define int long long

#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define endl '\n'
#define fi first
#define se second

using namespace __gnu_pbds;
using namespace std;
const int mod=1e9+7;
 // const int mod=998244353;
 // const int mod=1e9+9;
const int INF=4e18+10;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define read(n) int n; cin>>n;
#define readv(x, n) vector<int> x(n); for(auto &i:x) cin>>i;
int multiply(int a, int b, int in_mod){return (a*b)%in_mod;}
int mult_identity(int a){return 1;}

auto power(auto a, int b, int in_mod)
{
    auto prod=mult_identity(a);
    auto mult=a%in_mod;
    while(b!=0)
    {
        if(b%2)
        {
            prod=multiply(prod,mult, in_mod);

        }
        mult=multiply(mult, mult,in_mod);
        b/=2;
    }
    return prod;
}
int mod_inv(int q, int in_mod)
{

    return power(q, in_mod-2,in_mod);
}

#define trie teraera
struct Trie
{
    int next[26];
    // char pch;
    // int p;
    // int go[26];
    // int get_link;
    int index;
    bool leaf;
    Trie(int _p =-1 , char _pch = 'a'-1)
    {
        // p=_p;
        // pch=_pch;
        fill_n(next, 26, -1);
        // fill_n(go, 26, -1);
        // get_link=-1;
        leaf=false;
        index=-1;
    }
};

vector<Trie>trie(1);
void add_string(string s, int index)
{
    int start=0;
    for(int i=0;i<s.size();i++)
    {
        if(trie[start].next[s[i]-'a']==-1)
        {
            trie[start].next[s[i]-'a']=trie.size();
            trie.emplace_back(Trie(start, s[i]));
        }
        start=trie[start].next[s[i]-'a'];
    }
    trie[start].leaf=true;
    trie[start].index=index;
}

// int go(int node, char ch);
// int get_link(int node)
// {
//     if(trie[node].get_link==-1)
//     {
//         if(node==0 || trie[node].p==0)
//             trie[node].get_link=0;
//         else
//             trie[node].get_link=go(trie[trie[node].p].get_link, trie[node].pch);

//     }
//     return trie[node].get_link;
// }

// int go(int node, char ch)
// {
//     int c=ch-'a'
//     if(trie[node].go[c]==-1)
//     {
//         if(trie[node].next[c]!=-1)
//             trie[node].go[c]=trie[node].next[c];
//         else
//             trie[node].go[c]=v==0?0:go(get_link(node),ch);
//     }
//     return trie[node].go[c];
// }

// int n_leaves(int node)
// {
//     if(trie[node].leaf_counts==-1)
//     {

//         if(node==0)
//             trie[node].leaf_counts=0;

//         else
//         {
//             if(trie[get_link(node)].leaf)
//                 trie[node].leaf_counts=get_link(node);

//         }
//     }
//     return trie[node].leaf;
// }

const int MAXN = 1000+10;
vector<vector<pair<int, int>>> adj(MAXN);
vector<vector<vector<int> >> capacity(MAXN, vector<vector<int >> (MAXN, vector<int>(1)));
vector<vector<vector<int> > > cost(MAXN, vector<vector<int>  > (MAXN, vector<int>(1)));

vector<pair<int, int> > real_parent(MAXN, {-1, -1});

int n,m , q;

void spfa(int s, vector<int> &d, vector<pair<int, int> >&p)
{
    queue<int> q;
    d[s]=0;
    q.push(s);
    while(!q.empty())
    {
        auto top = q.front();
        q.pop();
        for(auto v:adj[top])
        {
            if(capacity[top][v.fi][v.se]>0 && d[v.fi]>d[top]+cost[top][v.fi][v.se])
            {
                d[v.fi]=d[top]+cost[top][v.fi][v.se];
                q.push(v.fi);
                p[v.fi]={top, v.se};
            }
        }
    }

}

auto max_flow(int s, int t, int K)
{
    int mn_cost = 0;
    int mx_flow=0;
    while(true)
    {
        if(K==0)
            break;
        vector<int> d(n+m+2, INF);
        vector<pair<int, int> >  p(n+m+2, {-1,-1});
        spfa(s,d, p);
        if(d[t]==INF)
            break;
        int end=t;
        int flow=INF;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            flow=min(flow, capacity[p[end].fi][end][p[end].se]);
            end=p[end].fi;
        }
        if(flow==INF)
            break;
        flow=min(flow,K-flow);

        K-=flow;

        mn_cost+=d[t]*flow;

        mx_flow+=flow;
        end=t;
        while(p[end]!=make_pair((int)-1,(int)-1))
        {
            capacity[p[end].fi][end][p[end].se]-=flow;
            capacity[end][p[end].fi][p[end].se]+=flow;

            end=p[end].fi;
        }

    }
    return make_pair(mx_flow,mn_cost);
}

void solve()
{

    // for(auto &i:adj)
    // {
    //     i.clear();
    // }
    // for(auto &i:cost)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    // for(auto &i:capacity)
    // {
    //     i.clear();
    //     i.resize(MAXN);
    //     for(auto &j:i)
    //     {
    //         j.clear();
    //         j.resize(2);
    //     }
    // }
    cin>>n;

    string s;
    cin>>s;

    cin>>m;

    for(int i=0;i<m;i++)
    {
        string p;
        cin>>p;
        int val;
        cin>>val;
        int len =p.size();
        for(int l=0;l+len-1<n ;l++)
        {
            int r= l+len-1;
            bool flag=true;
            for(int j =l ;j<=r;j++)
            {
                if(s[j]!=p[j-l])
                {
                    flag=false;
                }
            }
            if(flag)
            {
                adj[l+1].pb({r+2,0});
                adj[r+2].pb({l+1,0});
                cost[l+1][r+2][0]=-val;
                cost[r+2][l+1][0]=+val;
                capacity[l+1][r+2][0]=1;
            }
        }
    }

    for(int i=1;i<=n+1;i++)
    {
        adj[i-1].pb({i,0});
        adj[i].pb({i-1,0});
        cost[i-1][i][0]=0;
        cost[i][i-1][0]=0;
        capacity[i-1][i][0]=INF;

    }

    // for(int i=1;i<=m;i++)
    // {

    //     int second =i;

    //     adj[n+second].pb({n+m+1, 0});
    //     adj[n+m+1].pb({n+second, 0});

    //     capacity[n+second][n+m+1][0] = w;

    //     adj[u].pb({n+second,0});
    //     adj[n+second].pb({u,0});
    //     capacity[u][n+second][0]=INF;

    //     adj[v].pb({n+second,0});
    //     adj[n+second].pb({v,0});
    //     capacity[v][n+second][0]=INF;

    // }

    // for(int j=1;j<=n;j++)
    // {
    //     adj[n+j].pb({n+n+1,0});
    //     adj[n+n+1].pb({n+j, 0});
    //     cost[n+j][n+n+1][0]=0;
    //     cost[n+n+1][n+j][0]=0;
    //     capacity[n+j][n+n+1][0]=1;

    // }
    int x;
    cin>>x;
    auto ans=max_flow(0, n+1, x);
    // cout<<ans.fi<<" "<<ans.se<<endl;
    cout<<-ans.se<<endl;

}
signed main()

{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
        freopen ("INPUT.txt" , "r" , stdin);
        freopen ("OUTPUT.txt" , "w" , stdout);
    }
    #endif
    auto clk=clock();
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    // -------------------------------------Code starts here---------------------------------------------------------------------

    int t=1;
    // cin>>t;
    for(int test=1;test<=t;test++)
    {
        // cout<<"Case #"<<test<<": ";
        // cout<<endl;
        solve();
        // cout<<endl;

    }

    // -------------------------------------Code ends here------------------------------------------------------------------

    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "Time: " << ((double)clk)/CLOCKS_PER_SEC << "\n";
    return 0;
}


#include <bits/stdc++.h>
#ifdef _MSC_VER
#define __builtin_popcount (int)__popcnt
#define __builtin_popcountll (int)__popcnt64
#define __builtin_clz (int)__lzcnt
#define $ system("pause")
#define gp_hash_table unordered_map
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
#define $
//#define USACO
//#define IOI_style
#endif

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef complex<double> point;

#define MOD ll(998244353)
#define MAXN int(500 + 10)
#define LG 20
#define inf_int int(1e9 + 100)
#define inf_ll ll(1e18 + 100)
#define PI 3.14159265359

#define rep(i, j, k) for (int i = j; i < k; i++)
#define for_all(x) x.begin(), x.end()
#define lid id << 1
#define rid id << 1 | 1
#define lch l, mid, lid
#define rch mid, r, rid
#define pb push_back
#define X first
#define Y second
#define re real()
#define im imag()

template <typename S, typename T>
inline ostream &operator<<(ostream &out, const pair<S, T> &p)
{
	return out << "( " << p.X << " , " << p.Y << " )";
}
template <typename S>
inline ostream &operator<<(ostream &out, const vector<S> &p)
{
	for (auto &e : p) out << e; return out;
}
template <typename T, typename S>
inline T smin(T &a, const S &b) { return a > b ? a = b : a; }
template <typename T, typename S>
inline T smax(T &a, const S &b) { return a < b ? a = b : a; }
inline double dot(const point l, const point r) { return l.re * r.re + l.im * r.im; }
inline double cross(const point l, const point r) { return l.re * r.im - l.im * r.re; }
ll po(ll v, ll u) { return u ? (po(v * v % MOD, u >> 1) * (u & 1 ? v : 1) % MOD) : 1; }
inline void add(ll &l, const ll &r) { l = (l + r) % MOD; }
ll gcd(ll v, ll u) { return u ? gcd(u, v % u) : v; }

struct MCMF {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		ll p;
		inline Edge(int u , int v, int c, double p): u(u), v(v), c(c), p(p) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q;
	vector<ll> dist;
	vector<bool> active;
	int Ql, Qr;
	inline void push(int v) {
		if (active[v]) return;
		active[v] = true;
		Q[Qr++] = v;
		if (Qr == n) Qr = 0;
	}
	inline int pop() {
		int res = Q[Ql++];
		if (Ql == n) Ql = 0;
		active[res] = false;
		return res;
	}
	inline void addEdge(int u, int v, int c = 1 ,ll p = 0) {
		adj[u].pb(m++); e.pb(Edge(u, v, c, p));
		adj[v].pb(m++); e.pb(Edge(v, u, 0, -p));
	}
	inline MCMF() {}
	inline MCMF(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
		active.resize(n);
	}
	inline bool spfa() {
		fill(for_all(dist), inf_ll);
		fill(for_all(active), false);
		Ql = Qr = 0;
		dist[So] = 0;
		push(So);
		while (Ql != Qr) {
			int u = pop();
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + e[ed].p < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + e[ed].p;
					ptr[e[ed].v] = ed;
					push(e[ed].v);
				}
		}
		return dist[Sy] != inf_ll;
	}
	inline int relax() {
		int me = Sy;
		int mn = inf_int;
		while (me != So) {
			smin(mn, e[ptr[me]].c);
			me = e[ptr[me]].u;
		}
		me = Sy;
		while (me != So) {
			e[ptr[me]].c -= mn;
			e[ptr[me] ^ 1].c += mn;
			me = e[ptr[me]].u;
		}
		return mn;
	}
	pll minCost() {
		ll max_flow = 0;
		ll min_cost = 0;
		while (spfa()) {
			ll g = relax();
			min_cost += g * dist[Sy];
			max_flow += g;
		}
		return { max_flow , min_cost };
	}
};
///////////////////////////////////////////////////////////////////////
struct Dinic {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		inline Edge(int u, int v, int c) : u(u), v(v), c(c) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q, dist;
	int Ql, Qr;
	inline void addEdge(int u, int v, int c) {
		adj[u].pb(m++); e.pb(Edge(u, v, c));
		adj[v].pb(m++); e.pb(Edge(v, u, 0));
	}
	inline Dinic() {}
	inline Dinic(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		//e.reserve(2 * m);
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
	}
	inline bool bfs() {
		fill(for_all(dist), inf_int);
		Ql = Qr = 0;
		dist[So] = 0;
		Q[Qr++] = So;
		while (Ql != Qr) {
			int u = Q[Ql++];
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + 1 < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + 1;
					Q[Qr++] = e[ed].v;
				}
		}
		return dist[Sy] != inf_int;
	}
	inline int dfs(int u, int f = inf_int) {
		int CAN = 0;
		if (u == Sy) return f;
		for (int &v = ptr[u]; v < (int)adj[u].size(); v++) {
			Edge id = e[adj[u][v]];
			if (dist[u] + 1 == dist[id.v] && id.c)
				if (int g = dfs(id.v, min(f, id.c))) {
					e[adj[u][v]].c -= g;
					e[adj[u][v] ^ 1].c += g;
					return g;
				}
		}
		return CAN;
	}
	int maxFlow() {
		int max_flow = 0;
		while (bfs()) {
			fill(for_all(ptr), 0);
			while (int g = dfs(So)) {
				max_flow += g;
			}
		}
		return max_flow;
	}
};

MCMF mf;

int n, m, x, v[MAXN];
string s, t[MAXN];

#ifndef IOI_style
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
#ifdef USACO
	freopen("gathering.in", "r", stdin);
	freopen("gathering.out", "w", stdout);
#endif
	cin >> n >> s >> m;
	rep(i, 0, m) cin >> t[i] >> v[i];
	cin >> x;
	mf = MCMF(n + 2);
	rep(i, 0, n + 1)
		mf.addEdge(i, i + 1, x, 0);
	rep(i, 0, m)
		rep(j, 0, n - (int)t[i].size() + 1)
			if (s.substr(j, t[i].size()) == t[i])
				mf.addEdge(1 + j, 1 + j + t[i].size(), 1, -v[i]);
	cout << -mf.minCost().Y << endl;
	$;
	return 0;
}
#endif


#include <bits/stdc++.h>
#ifdef _MSC_VER
#define __builtin_popcount (int)__popcnt
#define __builtin_popcountll (int)__popcnt64
#define __builtin_clz (int)__lzcnt
#define $ system("pause")
#define gp_hash_table unordered_map
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
#define $
//#define USACO
//#define IOI_style
#endif

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef complex<double> point;

#define MOD ll(998244353)
#define MAXN int(500 + 10)
#define LG 20
#define inf_int int(1e9 + 100)
#define inf_ll ll(1e18 + 100)
#define PI 3.14159265359

#define rep(i, j, k) for (int i = j; i < k; i++)
#define for_all(x) x.begin(), x.end()
#define lid id << 1
#define rid id << 1 | 1
#define lch l, mid, lid
#define rch mid, r, rid
#define pb push_back
#define X first
#define Y second
#define re real()
#define im imag()

template <typename S, typename T>
inline ostream &operator<<(ostream &out, const pair<S, T> &p)
{
	return out << "( " << p.X << " , " << p.Y << " )";
}
template <typename S>
inline ostream &operator<<(ostream &out, const vector<S> &p)
{
	for (auto &e : p) out << e; return out;
}
template <typename T, typename S>
inline T smin(T &a, const S &b) { return a > b ? a = b : a; }
template <typename T, typename S>
inline T smax(T &a, const S &b) { return a < b ? a = b : a; }
inline double dot(const point l, const point r) { return l.re * r.re + l.im * r.im; }
inline double cross(const point l, const point r) { return l.re * r.im - l.im * r.re; }
ll po(ll v, ll u) { return u ? (po(v * v % MOD, u >> 1) * (u & 1 ? v : 1) % MOD) : 1; }
inline void add(ll &l, const ll &r) { l = (l + r) % MOD; }
ll gcd(ll v, ll u) { return u ? gcd(u, v % u) : v; }

struct MCMF {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		ll p;
		inline Edge(int u , int v, int c, double p): u(u), v(v), c(c), p(p) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q;
	vector<ll> dist;
	vector<bool> active;
	int Ql, Qr;
	inline void push(int v) {
		if (active[v]) return;
		active[v] = true;
		Q[Qr++] = v;
		if (Qr == n) Qr = 0;
	}
	inline int pop() {
		int res = Q[Ql++];
		if (Ql == n) Ql = 0;
		active[res] = false;
		return res;
	}
	inline void addEdge(int u, int v, int c = 1 ,ll p = 0) {
		adj[u].pb(m++); e.pb(Edge(u, v, c, p));
		adj[v].pb(m++); e.pb(Edge(v, u, 0, -p));
	}
	inline MCMF() {}
	inline MCMF(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
		active.resize(n);
	}
	inline bool spfa() {
		fill(for_all(dist), inf_ll);
		fill(for_all(active), false);
		Ql = Qr = 0;
		dist[So] = 0;
		push(So);
		while (Ql != Qr) {
			int u = pop();
			cout << " :: " << u << endl;
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + e[ed].p < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + e[ed].p;
					ptr[e[ed].v] = ed;
					push(e[ed].v);
				}
		}
		return dist[Sy] != inf_ll;
	}
	inline int relax() {
		int me = Sy;
		int mn = inf_int;
		while (me != So) {
			smin(mn, e[ptr[me]].c);
			me = e[ptr[me]].u;
		}
		me = Sy;
		while (me != So) {
			e[ptr[me]].c -= mn;
			e[ptr[me] ^ 1].c += mn;
			me = e[ptr[me]].u;
		}
		return mn;
	}
	pll minCost() {
		ll max_flow = 0;
		ll min_cost = 0;
		while (spfa()) {
			ll g = relax();
			min_cost += g * dist[Sy];
			max_flow += g;
		}
		return { max_flow , min_cost };
	}
};
///////////////////////////////////////////////////////////////////////
struct Dinic {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		inline Edge(int u, int v, int c) : u(u), v(v), c(c) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q, dist;
	int Ql, Qr;
	inline void addEdge(int u, int v, int c) {
		adj[u].pb(m++); e.pb(Edge(u, v, c));
		adj[v].pb(m++); e.pb(Edge(v, u, 0));
	}
	inline Dinic() {}
	inline Dinic(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		//e.reserve(2 * m);
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
	}
	inline bool bfs() {
		fill(for_all(dist), inf_int);
		Ql = Qr = 0;
		dist[So] = 0;
		Q[Qr++] = So;
		while (Ql != Qr) {
			int u = Q[Ql++];
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + 1 < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + 1;
					Q[Qr++] = e[ed].v;
				}
		}
		return dist[Sy] != inf_int;
	}
	inline int dfs(int u, int f = inf_int) {
		int CAN = 0;
		if (u == Sy) return f;
		for (int &v = ptr[u]; v < (int)adj[u].size(); v++) {
			Edge id = e[adj[u][v]];
			if (dist[u] + 1 == dist[id.v] && id.c)
				if (int g = dfs(id.v, min(f, id.c))) {
					e[adj[u][v]].c -= g;
					e[adj[u][v] ^ 1].c += g;
					return g;
				}
		}
		return CAN;
	}
	int maxFlow() {
		int max_flow = 0;
		while (bfs()) {
			fill(for_all(ptr), 0);
			while (int g = dfs(So)) {
				max_flow += g;
			}
		}
		return max_flow;
	}
};

MCMF mf;

int n, m, x, v[MAXN];
string s, t[MAXN];

#ifndef IOI_style
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
#ifdef USACO
	freopen("gathering.in", "r", stdin);
	freopen("gathering.out", "w", stdout);
#endif
	cin >> n >> s >> m;
	rep(i, 0, m) cin >> t[i] >> v[i];
	cin >> x;
	mf = MCMF(n + 2);
	rep(i, 0, n + 1)
		mf.addEdge(i, i + 1, x, 0);
	rep(i, 0, m)
		rep(j, 0, n - (int)t[i].size() + 1)
			if (s.substr(j, t[i].size()) == t[i])
				mf.addEdge(1 + j, 1 + j + t[i].size(), 1, -v[i]);
	cout << -mf.minCost().Y << endl;
	$;
	return 0;
}
#endif


#include <bits/stdc++.h>
#ifdef _MSC_VER
#define __builtin_popcount (int)__popcnt
#define __builtin_popcountll (int)__popcnt64
#define __builtin_clz (int)__lzcnt
#define $ system("pause")
#define gp_hash_table unordered_map
#define bug cout
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
#define $
#define bug 1
//#define USACO
//#define IOI_style
#endif

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef complex<double> point;

#define MOD ll(998244353)
#define MAXN int(500 + 10)
#define LG 20
#define inf_int int(1e9 + 100)
#define inf_ll ll(1e18 + 100)
#define PI 3.14159265359

#define rep(i, j, k) for (int i = j; i < k; i++)
#define for_all(x) x.begin(), x.end()
#define lid id << 1
#define rid id << 1 | 1
#define lch l, mid, lid
#define rch mid, r, rid
#define pb push_back
#define X first
#define Y second
#define re real()
#define im imag()

template <typename S, typename T>
inline ostream &operator<<(ostream &out, const pair<S, T> &p)
{
	return out << "( " << p.X << " , " << p.Y << " )";
}
template <typename S>
inline ostream &operator<<(ostream &out, const vector<S> &p)
{
	for (auto &e : p) out << e; return out;
}
template <typename T, typename S>
inline T smin(T &a, const S &b) { return a > b ? a = b : a; }
template <typename T, typename S>
inline T smax(T &a, const S &b) { return a < b ? a = b : a; }
inline double dot(const point l, const point r) { return l.re * r.re + l.im * r.im; }
inline double cross(const point l, const point r) { return l.re * r.im - l.im * r.re; }
ll po(ll v, ll u) { return u ? (po(v * v % MOD, u >> 1) * (u & 1 ? v : 1) % MOD) : 1; }
inline void add(ll &l, const ll &r) { l = (l + r) % MOD; }
ll gcd(ll v, ll u) { return u ? gcd(u, v % u) : v; }

struct MCMF {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		ll p;
		inline Edge(int u , int v, int c, double p): u(u), v(v), c(c), p(p) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q;
	vector<ll> dist;
	vector<bool> active;
	int Ql, Qr;
	inline void push(int v) {
		if (active[v]) return;
		active[v] = true;
		Q[Qr++] = v;
		if (Qr == n) Qr = 0;
	}
	inline int pop() {
		int res = Q[Ql++];
		if (Ql == n) Ql = 0;
		active[res] = false;
		return res;
	}
	inline void addEdge(int u, int v, int c = 1 ,ll p = 0) {
		adj[u].pb(m++); e.pb(Edge(u, v, c, p));
		adj[v].pb(m++); e.pb(Edge(v, u, 0, -p));
	}
	inline MCMF() {}
	inline MCMF(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
		active.resize(n);
	}
	inline bool spfa() {
		fill(for_all(dist), inf_ll);
		fill(for_all(active), false);
		Ql = Qr = 0;
		dist[So] = 0;
		push(So);
		while (Ql != Qr) {
			int u = pop();
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + e[ed].p < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + e[ed].p;
					ptr[e[ed].v] = ed;
					push(e[ed].v);
				}
		}
		return dist[Sy] != inf_ll;
	}
	inline int relax() {
		int me = Sy;
		int mn = inf_int;
		while (me != So) {
			smin(mn, e[ptr[me]].c);
			me = e[ptr[me]].u;
		}
		me = Sy;
		while (me != So) {
			e[ptr[me]].c -= mn;
			e[ptr[me] ^ 1].c += mn;
			me = e[ptr[me]].u;
		}
		return mn;
	}
	pll minCost() {
		ll max_flow = 0;
		ll min_cost = 0;
		while (spfa()) {
			ll g = relax();
			min_cost += g * dist[Sy];
			max_flow += g;
		}
		return { max_flow , min_cost };
	}
};
///////////////////////////////////////////////////////////////////////
struct Dinic {
	int n, m = 0, So, Sy;
	struct Edge {
		int u, v, c;
		inline Edge(int u, int v, int c) : u(u), v(v), c(c) {}
	};
	vector<Edge> e;
	vector<vector<int>> adj;
	vector<int> ptr, Q, dist;
	int Ql, Qr;
	inline void addEdge(int u, int v, int c) {
		adj[u].pb(m++); e.pb(Edge(u, v, c));
		adj[v].pb(m++); e.pb(Edge(v, u, 0));
	}
	inline Dinic() {}
	inline Dinic(int n, int So = 0, int Sy = -1) : n(n), So(So), Sy(Sy) {
		if (Sy == -1) this->Sy = n - 1;
		//e.reserve(2 * m);
		adj.resize(n);
		ptr.resize(n);
		Q.resize(n);
		dist.resize(n);
	}
	inline bool bfs() {
		fill(for_all(dist), inf_int);
		Ql = Qr = 0;
		dist[So] = 0;
		Q[Qr++] = So;
		while (Ql != Qr) {
			int u = Q[Ql++];
			for (auto ed : adj[u])
				if (e[ed].c && dist[u] + 1 < dist[e[ed].v]) {
					dist[e[ed].v] = dist[u] + 1;
					Q[Qr++] = e[ed].v;
				}
		}
		return dist[Sy] != inf_int;
	}
	inline int dfs(int u, int f = inf_int) {
		int CAN = 0;
		if (u == Sy) return f;
		for (int &v = ptr[u]; v < (int)adj[u].size(); v++) {
			Edge id = e[adj[u][v]];
			if (dist[u] + 1 == dist[id.v] && id.c)
				if (int g = dfs(id.v, min(f, id.c))) {
					e[adj[u][v]].c -= g;
					e[adj[u][v] ^ 1].c += g;
					return g;
				}
		}
		return CAN;
	}
	int maxFlow() {
		int max_flow = 0;
		while (bfs()) {
			fill(for_all(ptr), 0);
			while (int g = dfs(So)) {
				max_flow += g;
			}
		}
		return max_flow;
	}
};

MCMF mf;

int n, m, x, v[MAXN];
string s, t[MAXN];

#ifndef IOI_style
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
#ifdef USACO
	freopen("gathering.in", "r", stdin);
	freopen("gathering.out", "w", stdout);
#endif
	cin >> n >> s >> m;
	bug << n << s << m;
	rep(i, 0, m) cin >> t[i] >> v[i];
	cin >> x;
	mf = MCMF(n + 2);
	rep(i, 0, n + 1)
		mf.addEdge(i, i + 1, x, 0);
	rep(i, 0, m)
		rep(j, 0, n - (int)t[i].size() + 1)
			if (s.substr(j, t[i].size()) == t[i])
				mf.addEdge(1 + j, 1 + j + t[i].size(), 1, -v[i]);
	cout << -mf.minCost().Y << endl;
	$;
	return 0;
}
#endif


#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1<<28;
const double EPS=1e-6;

struct SCC{
    int n, d=0, cnt=0;
    vector<vector<int>> edg;
    vector<int> com, dfn, low;
    stack<int> S;
    SCC(int _n) : n(_n), edg(n+1), com(n+1, 0), dfn(n+1, 0), low(n+1){}
    void add(int u, int v){
        edg[u].push_back(v);
    }
    void dfs(int u){
        dfn[u]=low[u]=++d;
        S.push(u);
        for(int v : edg[u]){
            if( !dfn[v] ) dfs(v);
            if( !com[v] ) low[u]=min(low[u], low[v]);
        }
        if( dfn[u]==low[u] ){
            cnt++;
            for(int v; v=S.top(), S.pop(), com[v]=cnt, v!=u; );
        }
    }
    void operator()(){//0-base or 1-base
        for(int i=1; i<=n; i++) if( !dfn[i] ) dfs(i);
    }
};
struct edge{
    int u, v, w, c, x, r;
    edge(int _u=0, int _v=0, int _w=0, int _c=0, int _x=0, int _r=0) :
    u(_u), v(_v), w(_w), c(_c), x(_x), r(_r){}
};
struct howard{
    int n; vector<edge> e; vector<double> d; vector<int> c, p, x;
    howard(int _n, const vector<edge> &_e) :
    n(_n), e(_e), d(n+1, INF), c(n+1), p(n+1), x(n+1){}
    pair<double, vector<int>> operator()(){
        for (const edge& E : e) if( d[E.u]>E.c )
            d[E.u]=c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        for(double ld; ; ){
            int s; get_cycle(ld, s); reverse_dfs(ld, s);
            if( !improve(ld) ){ get_cycle(ld, s);
                vector<int> C; C.push_back(x[s]);
                for(int u=p[s]; u!=s; u=p[u]) C.push_back(x[u]);
                return pair<double, vector<int>>(ld, C);
            }
        }
    }
    void get_cycle(double& ld, int& s){
        ld=INF; s=0; vector<int> vis(n+1, 0), dis(n+1, 0);
        for(int i=1; i<=n; i++){ vis[i]= !vis[i] ? 1 : -1;
            for(int u=i; vis[u]>=0; u=p[u]){ int v=p[u];
                if( !vis[v] ) vis[v]=vis[u]+1, dis[v]=dis[u]+c[u];
                else if( vis[v]>0 ){
                    double len=(double)(dis[u]+c[u]-dis[v])/(vis[u]+1-vis[v]);
                    if( ld>len ) ld=len, s=u;
                    break;
                }
            }
            for (int u=i; vis[u]>=0; u=p[u]) vis[u]=-1;
        }
    }
    void reverse_dfs(double ld, int s){
        vector<vector<int>> pre(n + 1); queue<int> Q;
        for(int i=1; i<=n; i++) if( i!=s ) pre[ p[i] ].push_back(i);
        for(Q.push(s); !Q.empty(); Q.pop()){ int v=Q.front();
            for(int u : pre[v]) d[u]=d[v]+c[u]-ld, Q.push(u);
        }
    }
    bool improve(double ld){
        bool ans=false;
        for(const edge& E : e){
            double nd=d[E.v]+E.c-ld, dt=d[E.u]-nd;
            if( dt>0 ) ans|=dt>EPS, d[E.u]=nd, c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        }
        return ans;
    }
};
struct mcc{
	int n; vector<edge> e; SCC S;
	mcc(int _n) : n(_n), S(n){}
	void add(int u, int v, int w, int c){
		if( w>0 ) e.push_back(edge(u, v, w, c)), S.add(u, v);
	}
	int operator()(){ S();//1-base
		int ans=0; vector<vector<edge>> f(S.cnt+1);
		vector<int> idx(n+1, 0), cnt(n+1, 0);
		for(int i=1; i<=n; i++) idx[i]=++cnt[ S.com[i] ];
		for(const edge& E : e) if( S.com[E.u]==S.com[E.v] )
			f[ S.com[E.u] ].push_back(edge(idx[E.u], idx[E.v], E.w, E.c));
		for(int i=1; i<=S.cnt; i++) if( !f[i].empty() )//scc, 1 vertex, no edge, no cycle
			ans+=mcc_scc_cycle(cnt[i], f[i]);//scc, >=1 vertex, >=1 edge, >=1 cycle
		return ans;
	}
	int mcc_scc_cycle(int n, vector<edge>& e){
		for(int m=e.size(), i=0; i<m; i++){
			e.push_back(edge(e[i].v, e[i].u, 0, -e[i].c, i+m, i));
			e[i].x=i, e[i].r=i+m;
		}
		int ans=0;
		for(; ; ){
			vector<edge> f;
			for(const edge& E : e) if( E.w>0 ) f.push_back(E);
			pair<double, vector<int>> pa=howard(n, f)();
			if( pa.first>-EPS ) break;
			int minw=INF;
			for(int x : pa.second) minw=min(minw, e[x].w);
			for(int x : pa.second){ ans+=minw*e[x].c;
				e[x].w-=minw; e[e[x].r].w+=minw;
			}
		}
		return ans;
	}
};

int main()
{
    int n, m, x;
    char s[1<<10]={0};
    scanf("%d%s%d", &n, s, &m);
    mcc M(n+1);

    for(; m>0; m--)
    {
        char t[1<<10]={0};
        scanf("%s%d", t, &x);
        int l=strlen(t);

        for(int i=0; i+l<=n; i++)
            if( !strncmp(s+i, t, l) )
                M.add(i+l, i, 1, -x);
    }

    scanf("%d", &x);

    for(int i=0; i<n; i++)
        M.add(i, i+1, x, 0);

    printf("%d\n", -M());
}


#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1<<28;
const double EPS=1e-4;

struct SCC{
    int n, d=0, cnt=0;
    vector<vector<int>> edg;
    vector<int> com, dfn, low;
    stack<int> S;
    SCC(int _n) : n(_n), edg(n+1), com(n+1, 0), dfn(n+1, 0), low(n+1){}
    void add(int u, int v){
        edg[u].push_back(v);
    }
    void dfs(int u){
        dfn[u]=low[u]=++d;
        S.push(u);
        for(int v : edg[u]){
            if( !dfn[v] ) dfs(v);
            if( !com[v] ) low[u]=min(low[u], low[v]);
        }
        if( dfn[u]==low[u] ){
            cnt++;
            for(int v; v=S.top(), S.pop(), com[v]=cnt, v!=u; );
        }
    }
    void operator()(){//0-base or 1-base
        for(int i=1; i<=n; i++) if( !dfn[i] ) dfs(i);
    }
};
struct edge{
    int u, v, w, c, x, r;
    edge(int _u=0, int _v=0, int _w=0, int _c=0, int _x=0, int _r=0) :
    u(_u), v(_v), w(_w), c(_c), x(_x), r(_r){}
};
struct howard{
    int n; vector<edge> e; vector<double> d; vector<int> c, p, x;
    howard(int _n, const vector<edge> &_e) :
    n(_n), e(_e), d(n+1, INF), c(n+1), p(n+1), x(n+1){}
    pair<double, vector<int>> operator()(){
        for (const edge& E : e) if( d[E.u]>E.c )
            d[E.u]=c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        for(double ld; ; ){
            int s; get_cycle(ld, s); reverse_dfs(ld, s);
            if( !improve(ld) ){ get_cycle(ld, s);
                vector<int> C; C.push_back(x[s]);
                for(int u=p[s]; u!=s; u=p[u]) C.push_back(x[u]);
                return pair<double, vector<int>>(ld, C);
            }
        }
    }
    void get_cycle(double& ld, int& s){
        ld=INF; s=0; vector<int> vis(n+1, 0), dis(n+1, 0);
        for(int i=1; i<=n; i++){ vis[i]= !vis[i] ? 1 : -1;
            for(int u=i; vis[u]>=0; u=p[u]){ int v=p[u];
                if( !vis[v] ) vis[v]=vis[u]+1, dis[v]=dis[u]+c[u];
                else if( vis[v]>0 ){
                    double len=(double)(dis[u]+c[u]-dis[v])/(vis[u]+1-vis[v]);
                    if( ld>len ) ld=len, s=u;
                    break;
                }
            }
            for (int u=i; vis[u]>=0; u=p[u]) vis[u]=-1;
        }
    }
    void reverse_dfs(double ld, int s){
        vector<vector<int>> pre(n + 1); queue<int> Q;
        for(int i=1; i<=n; i++) if( i!=s ) pre[ p[i] ].push_back(i);
        for(Q.push(s); !Q.empty(); Q.pop()){ int v=Q.front();
            for(int u : pre[v]) d[u]=d[v]+c[u]-ld, Q.push(u);
        }
    }
    bool improve(double ld){
        bool ans=false;
        for(const edge& E : e){
            double nd=d[E.v]+E.c-ld, dt=d[E.u]-nd;
            if( dt>0 ) ans|=dt>EPS, d[E.u]=nd, c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        }
        return ans;
    }
};
struct mcc{
	int n; vector<edge> e; SCC S;
	mcc(int _n) : n(_n), S(n){}
	void add(int u, int v, int w, int c){
		if( w>0 ) e.push_back(edge(u, v, w, c)), S.add(u, v);
	}
	int operator()(){ S();//1-base
		int ans=0; vector<vector<edge>> f(S.cnt+1);
		vector<int> idx(n+1, 0), cnt(n+1, 0);
		for(int i=1; i<=n; i++) idx[i]=++cnt[ S.com[i] ];
		for(const edge& E : e) if( S.com[E.u]==S.com[E.v] )
			f[ S.com[E.u] ].push_back(edge(idx[E.u], idx[E.v], E.w, E.c));
		for(int i=1; i<=S.cnt; i++) if( !f[i].empty() )//scc, 1 vertex, no edge, no cycle
			ans+=mcc_scc_cycle(cnt[i], f[i]);//scc, >=1 vertex, >=1 edge, >=1 cycle
		return ans;
	}
	int mcc_scc_cycle(int n, vector<edge>& e){
		for(int m=e.size(), i=0; i<m; i++){
			e.push_back(edge(e[i].v, e[i].u, 0, -e[i].c, i+m, i));
			e[i].x=i, e[i].r=i+m;
		}
		int ans=0;
		for(; ; ){
			vector<edge> f;
			for(const edge& E : e) if( E.w>0 ) f.push_back(E);
			pair<double, vector<int>> pa=howard(n, f)();
			if( pa.first>-EPS ) break;
			int minw=INF;
			for(int x : pa.second) minw=min(minw, e[x].w);
			for(int x : pa.second){ ans+=minw*e[x].c;
				e[x].w-=minw; e[e[x].r].w+=minw;
			}
		}
		return ans;
	}
};

int main()
{
    int n, m, x;
    char s[1<<10]={0};
    scanf("%d%s%d", &n, s, &m);
    mcc M(n+1);

    for(; m>0; m--)
    {
        char t[1<<10]={0};
        scanf("%s%d", t, &x);
        int l=strlen(t);

        for(int i=0; i+l<=n; i++)
            if( !strncmp(s+i, t, l) )
                M.add(i+l, i, 1, -x);
    }

    scanf("%d", &x);

    for(int i=0; i<n; i++)
        M.add(i, i+1, x, 0);

    printf("%d\n", -M());
}


#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1<<28;
const double EPS=1e-6;

struct SCC{
    int n, d=0, cnt=0;
    vector<vector<int>> edg;
    vector<int> com, dfn, low;
    stack<int> S;
    SCC(int _n) : n(_n), edg(n+1), com(n+1, 0), dfn(n+1, 0), low(n+1){}
    void add(int u, int v){
        edg[u].push_back(v);
    }
    void dfs(int u){
        dfn[u]=low[u]=++d;
        S.push(u);
        for(int v : edg[u]){
            if( !dfn[v] ) dfs(v);
            if( !com[v] ) low[u]=min(low[u], low[v]);
        }
        if( dfn[u]==low[u] ){
            cnt++;
            for(int v; v=S.top(), S.pop(), com[v]=cnt, v!=u; );
        }
    }
    void operator()(){//0-base or 1-base
        for(int i=1; i<=n; i++) if( !dfn[i] ) dfs(i);
    }
};
struct edge{
    int u, v, w, c, x, r;
    edge(int _u=0, int _v=0, int _w=0, int _c=0, int _x=0, int _r=0) :
    u(_u), v(_v), w(_w), c(_c), x(_x), r(_r){}
};
struct howard{
    int n; vector<edge> e; vector<double> d; vector<int> c, p, x;
    howard(int _n, const vector<edge> &_e) :
    n(_n), e(_e), d(n+1, INF), c(n+1), p(n+1), x(n+1){}
    pair<double, vector<int>> operator()(){
        for (const edge& E : e) if( d[E.u]>E.c )
            d[E.u]=c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        for(double ld; ; ){
            int s; get_cycle(ld, s); reverse_dfs(ld, s);
            if( !improve(ld) ){ get_cycle(ld, s);
                vector<int> C; C.push_back(x[s]);
                for(int u=p[s]; u!=s; u=p[u]) C.push_back(x[u]);
                return pair<double, vector<int>>(ld, C);
            }
        }
    }
    void get_cycle(double& ld, int& s){
        ld=INF; s=0; vector<int> vis(n+1, 0), dis(n+1, 0);
        for(int i=1; i<=n; i++){ vis[i]= !vis[i] ? 1 : -1;
            for(int u=i; vis[u]>=0; u=p[u]){ int v=p[u];
                if( !vis[v] ) vis[v]=vis[u]+1, dis[v]=dis[u]+c[u];
                else if( vis[v]>0 ){
                    double len=(double)(dis[u]+c[u]-dis[v])/(vis[u]+1-vis[v]);
                    if( ld>len ) ld=len, s=u;
                    break;
                }
            }
            for (int u=i; vis[u]>=0; u=p[u]) vis[u]=-1;
        }
    }
    void reverse_dfs(double ld, int s){
        vector<vector<int>> pre(n + 1); queue<int> Q;
        for(int i=1; i<=n; i++) if( i!=s ) pre[ p[i] ].push_back(i);
        for(Q.push(s); !Q.empty(); Q.pop()){ int v=Q.front();
            for(int u : pre[v]) d[u]=d[v]+c[u]-ld, Q.push(u);
        }
    }
    bool improve(double ld){
        bool ans=false;
        for(const edge& E : e){
            double nd=d[E.v]+E.c-ld, dt=d[E.u]-nd;
            if( dt>0 ) ans|=dt>EPS, d[E.u]=nd, c[E.u]=E.c, p[E.u]=E.v, x[E.u]=E.x;
        }
        return ans;
    }
};
struct mcc{
	int n; vector<edge> e; SCC S;
	mcc(int _n) : n(_n), S(n){}
	void add(int u, int v, int w, int c){
		if( w>0 ) e.push_back(edge(u, v, w, c)), S.add(u, v);
	}
	int operator()(){ S();//1-base
		int ans=0; vector<vector<edge>> f(S.cnt+1);
		vector<int> idx(n+1, 0), cnt(n+1, 0);
		for(int i=1; i<=n; i++) idx[i]=++cnt[ S.com[i] ];
		for(const edge& E : e) if( S.com[E.u]==S.com[E.v] )
			f[ S.com[E.u] ].push_back(edge(idx[E.u], idx[E.v], E.w, E.c));
		for(int i=1; i<=S.cnt; i++) if( !f[i].empty() )//scc, 1 vertex, no edge, no cycle
			ans+=mcc_scc_cycle(cnt[i], f[i]);//scc, >=1 vertex, >=1 edge, >=1 cycle
		return ans;
	}
	int mcc_scc_cycle(int n, vector<edge>& e){
		for(int m=e.size(), i=0; i<m; i++){
			e.push_back(edge(e[i].v, e[i].u, 0, -e[i].c, i+m, i));
			e[i].x=i, e[i].r=i+m;
		}
		int ans=0;
		for(; ; ){
			vector<edge> f;
			for(const edge& E : e) if( E.w>0 ) f.push_back(E);
			pair<double, vector<int>> pa=howard(n, f)();
			if( pa.first>-EPS ) break;
			int minw=INF;
			for(int x : pa.second) minw=min(minw, e[x].w);
			for(int x : pa.second){ ans+=minw*e[x].c;
				e[x].w-=minw; e[e[x].r].w+=minw;
			}
		}
		return ans;
	}
};

int main()
{
    int n, m, x;
    char s[1<<10]={0};
    scanf("%d%s%d", &n, s, &m);
    mcc M(n);

    for(; m>0; m--)
    {
        char t[1<<10]={0};
        scanf("%s%d", t, &x);
        int l=strlen(t);

        for(int i=0; i+l<=n; i++)
            if( !strncmp(s+i, t, l) )
                M.add(i+l-1, i, 1, -x);
    }

    scanf("%d", &x);

    for(int i=1; i<n; i++)
        M.add(i-1, i, x, 0);

    printf("%d\n", -M());
}


#include <bits/stdc++.h>
#define pb          emplace_back
#define ll          long long
#define fi          first
#define se          second
#define mp          make_pair
#define int         int64_t

using namespace std;

const int N = (int)1e5 + 3;

const ll oo = (ll)1e15;
template<typename T> class mincost_maxflow { /// khong dung cho chu trinh am
  struct edge {
    int to;
    T cap, cost, flow;
  };

  int n, s, t;
  vector<vector<int>> adj;
  vector<edge> edges;
  vector<T> dist;
  vector<int> from;

public:
  const T inf = numeric_limits<T>::max();

  mincost_maxflow(int n, int s, int t)
  : n(n), s(s), t(t), adj(n), dist(n), from(n) { }

  inline void add(int u, int v, const T &cap, const T &cost) {
    adj[u].push_back(edges.size());
    edges.push_back({v, cap, cost, 0});
    adj[v].push_back(edges.size());
    edges.push_back({u, 0, -cost, 0});
  }

  bool spfa() {
    fill(dist.begin(), dist.end(), inf);
    vector<int> inq(n);
    queue<int> q;
    dist[s] = 0, inq[s] = true, q.push(s);
    while (q.size()) {
      int v = q.front();
      inq[v] = false, q.pop();
      for (int i : adj[v]) {
        edge &e = edges[i];
        if (e.cap > e.flow && dist[e.to] > dist[v] + e.cost) {
          dist[e.to] = dist[v] + e.cost;
          from[e.to] = i;
          if (!inq[e.to]) {
            inq[e.to] = true, q.push(e.to);
          }
        }
      }
    }
    return dist[t] < inf;
  }

  pair<T, T> get() {
    T cost = 0, flow = 0;
    while (spfa()) {
      T delta = inf;
      for (int v = t, i; v != s; v = edges[i ^ 1].to) {
        i = from[v];
        delta = min(delta, edges[i].cap - edges[i].flow);
      }
      for (int v = t, i; v != s; v = edges[i ^ 1].to) {
        i = from[v];
        edges[i].flow += delta;
        edges[i ^ 1].flow -= delta;
      }
      cost += dist[t] * delta;
      flow += delta;
    }
    return {cost, flow};
  }
};
int n, m, p, x;
string s, t;
bool found;

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    #define Task        "test"
    if(fopen(Task".inp", "r")) {
        freopen(Task".inp", "r", stdin);
        freopen(Task".out", "w", stdout);
    }
    cin >> n >> s >> m;
    mincost_maxflow<int> f(n + 2, n + 1, n);
    while(m --) {
        cin >> t >> p;
        for(int i = 0; i < n; ++i) {
            if(i + t.size() > n) break;
            found = 0;
            for(int j = 0; j < t.size(); ++j)
                if(s[i + j] != t[j]) {found = 1; break;}
            if(!found) {
                f.add(i, i + t.size(), 1, -p);
            }
        }
    }
    cin >> x;
    for(int i = 0; i < n; ++i) f.add(i, i + 1, x, 0);
    f.add(n + 1, 0, x, 0);
    cout << -f.get().fi;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

#define LL long long
#define int long long
#define ull unsigned long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<int, int>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 5e4+9;
constexpr int M = 1e9+7;
#ifdef int
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;
#else
constexpr int INF = 0x3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcf;
#endif

struct MCMF {
    static const int N = 5e3 + 5, M = 1e5 + 5;

    static const int INF = 0x3f3f3f3f3f3f3f3f;
    int n, m, tot = 1, lnk[N], cur[N], ter[M], nxt[M], cap[M], cost[M], dis[N], ret;
    bool vis[N];

    void add(int u, int v, int w, int c) {
        ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, cap[tot] = w, cost[tot] = c;
    }

    void addedge(int u, int v, int w, int c) { add(u, v, w, c), add(v, u, 0, -c); }

    bool spfa(int s, int t) {
        memset(dis, 0x3f, sizeof(dis));
        memcpy(cur, lnk, sizeof(lnk));
        std::queue<int> q;
        q.push(s), dis[s] = 0, vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop(), vis[u] = 0;
            for (int i = lnk[u]; i; i = nxt[i]) {
                int v = ter[i];
                if (cap[i] && dis[v] > dis[u] + cost[i]) {
                    dis[v] = dis[u] + cost[i];
                    if (!vis[v]) q.push(v), vis[v] = 1;
                }
            }
        }
        return dis[t] != INF;
    }

    int dfs(int u, int t, int flow) {
        if (u == t) return flow;
        vis[u] = 1;
        int ans = 0;
        for (int &i = cur[u]; i && ans < flow; i = nxt[i]) {
            int v = ter[i];
            if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) {
                int x = dfs(v, t, std::min(cap[i], flow - ans));
                if (x) ret += x * cost[i], cap[i] -= x, cap[i ^ 1] += x, ans += x;
            }
        }
        vis[u] = 0;
        return ans;
    }

    int mcmf(int s, int t) {
        int ans = 0;
        while (spfa(s, t)) {
            int x;
            while ((x = dfs(s, t, INF))) ans += x;
        }
        return ans;
    }
} g;

int n, m;
char str[105][505];
int len[105];
int p[105];

struct AC {

    int ch[N][26];
    int fail[N];
    int tot;
    vector<int> id[N];

    void clear() {
        for (int i = 0; i <= tot; i++)
            memset(ch[i], 0, sizeof(ch[i])),
                    fail[i] = 0;
        tot = 0;
    }

    void insert(int j, const char *s) {
        int u = 0;
        for (int i = 1; s[i]; i++) {
            int &v = ch[u][s[i] - 'a'];
            if (!v) v = ++tot;
            u = v;
        }
        id[u].emplace_back(j);
    }

    void build() {
        queue<int> q;
        for (int i = 0; i < 26; i++) {
            if (ch[0][i]) q.emplace(ch[0][i]);
        }
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = 0; i < 26; i++) {
                if (ch[u][i]) fail[ch[u][i]] = ch[fail[u]][i], q.emplace(ch[u][i]);
                else ch[u][i] = ch[fail[u]][i];
            }
        }
    }

    void go(const char* s) {
        int u = 0;
        for (int i = 1; s[i]; i++) {

            u = ch[u][s[i]-'a'];
            for (int j: id[u]) {
                g.addedge(i-len[j]+1, i+1, 1, -p[j]);
            }
            int f = fail[u];
            while (f) {
                for (int j: id[f]) {
                    g.addedge(i-len[j]+1, i+1, 1, -p[j]);
                }
                f = fail[f];
            }
        }
    }
} ac;

char t[505];
int x;

signed main() {
    fastio;
    cin >> n;
    cin >> (t+1);
    cin >> m;
    for (int i = 1; i <= m; i++) {
        cin >> (str[i]+1);
        len[i] = strlen(str[i]+1);
        cin >> p[i];
        ac.insert(i, str[i]);
    }
    cin >> x;
    int le = strlen(t+1);
    ac.build();
    ac.go(t);
    for (int i = 1; i <= le+1; i++) {
        g.addedge(i-1, i, x, 0);
    }
    g.mcmf(0, le+1);
    cout << -g.ret << "\n";
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

#define LL long long
#define int long long
#define ull unsigned long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<int, int>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 5e4+9;
constexpr int M = 1e9+7;
#ifdef int
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;
#else
constexpr int INF = 0x3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcf;
#endif

struct MCMF {
    static const int N = 5e3 + 5, M = 1e5 + 5;

    static const int INF = 0x3f3f3f3f3f3f3f3f;
    int n, m, tot = 1, lnk[N], cur[N], ter[M], nxt[M], cap[M], cost[M], dis[N], ret;
    bool vis[N];

    void add(int u, int v, int w, int c) {
        ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, cap[tot] = w, cost[tot] = c;
    }

    void addedge(int u, int v, int w, int c) { add(u, v, w, c), add(v, u, 0, -c); }

    bool spfa(int s, int t) {
        memset(dis, 0x3f, sizeof(dis));
        memcpy(cur, lnk, sizeof(lnk));
        std::queue<int> q;
        q.push(s), dis[s] = 0, vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop(), vis[u] = 0;
            for (int i = lnk[u]; i; i = nxt[i]) {
                int v = ter[i];
                if (cap[i] && dis[v] > dis[u] + cost[i]) {
                    dis[v] = dis[u] + cost[i];
                    if (!vis[v]) q.push(v), vis[v] = 1;
                }
            }
        }
        return dis[t] != INF;
    }

    int dfs(int u, int t, int flow) {
        if (u == t) return flow;
        vis[u] = 1;
        int ans = 0;
        for (int &i = cur[u]; i && ans < flow; i = nxt[i]) {
            int v = ter[i];
            if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) {
                int x = dfs(v, t, std::min(cap[i], flow - ans));
                if (x) ret += x * cost[i], cap[i] -= x, cap[i ^ 1] += x, ans += x;
            }
        }
        vis[u] = 0;
        return ans;
    }

    int mcmf(int s, int t) {
        int ans = 0;
        while (spfa(s, t)) {
            int x;
            while ((x = dfs(s, t, INF))) ans += x;
        }
        return ans;
    }
} g;

int n, m;
char str[105][505];
int len[105];
int p[105];

struct AC {

    int ch[N][26];
    int fail[N];
    int tot;
    vector<int> id[N];

    void clear() {
        for (int i = 0; i <= tot; i++)
            memset(ch[i], 0, sizeof(ch[i])),
                    fail[i] = 0;
        tot = 0;
    }

    void insert(int j, const char *s) {
        int u = 0;
        for (int i = 1; s[i]; i++) {
            int &v = ch[u][s[i] - 'a'];
            if (!v) v = ++tot;
            u = v;
        }
        id[u].emplace_back(j);
    }

    void build() {
        queue<int> q;
        for (int i = 0; i < 26; i++) {
            if (ch[0][i]) q.emplace(ch[0][i]);
        }
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = 0; i < 26; i++) {
                if (ch[u][i]) fail[ch[u][i]] = ch[fail[u]][i], q.emplace(ch[u][i]);
                else ch[u][i] = ch[fail[u]][i];
            }
        }
    }

    void go(const char* s) {
        int u = 0;
        for (int i = 1; s[i]; i++) {

            u = ch[u][s[i]-'a'];
            for (int j: id[u]) {
                g.addedge(i-len[j], i, 1, -p[j]);
            }
            int f = fail[u];
            while (f) {
                for (int j: id[f]) {
                    g.addedge(i-len[j], i, 1, -p[j]);
                }
                f = fail[f];
            }
        }
    }
} ac;

char t[505];
int x;

signed main() {
    fastio;
    cin >> n;
    cin >> (t+1);
    cin >> m;
    for (int i = 1; i <= m; i++) {
        cin >> (str[i]+1);
        len[i] = strlen(str[i]+1);
        cin >> p[i];
        ac.insert(i, str[i]);
    }
    cin >> x;
    int le = strlen(t+1);
    ac.build();
    ac.go(t);
    for (int i = 1; i <= le; i++) {
        g.addedge(i-1, i, x, 0);
    }
    g.mcmf(0, le);
    cout << -g.ret << "\n";
    return 0;
}