#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s, cur;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
};

vec <Edge> edge;

struct Graph {
    int dst[N];
    int par[N];
    int ind[N];
    vec <pii> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb({v, cur});
    edge.pb({c, 0, -w});
    cur++;
    graph.adj[v].pb({u, cur});
    edge.pb({c, c, w});
    cur++;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(pii p: graph.adj[u]) {
                int v = p.xx;
                int i = p.yy;
                int w = edge[i].wgt;
                if(edge[i].cap > edge[i].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    graph.ind[v] = i;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            int i = graph.ind[v];
            edge[i].flw++;
            edge[i ^ 1].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s, cur;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N];

struct Graph {
    int dst[N];
    int par[N];
    int ind[N];
    vec <pii> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb({v, cur});
    edge[cur].cap = c;
    edge[cur].flw = 0;
    edge[cur].wgt = -w;
    cur++;
    graph.adj[v].pb({u, cur});
    edge[cur].cap = c;
    edge[cur].flw = c;
    edge[cur].wgt = w;
    cur++;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(pii p: graph.adj[u]) {
                int v = p.xx;
                int i = p.yy;
                int w = edge[i].wgt;
                if(edge[i].cap > edge[i].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    graph.ind[v] = i;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            int i = graph.ind[v];
            edge[i].flw++;
            edge[i ^ 1].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s, cur;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
};

vec <Edge> edge;

struct Graph {
    int dst[N];
    int par[N];
    int ind[N];
    bool inq[N];
    vec <pii> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb({v, cur});
    edge.pb({c, 0, -w});
    cur++;
    graph.adj[v].pb({u, cur});
    edge.pb({c, c, w});
    cur++;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            graph.inq[u] = 0;

            for(pii p: graph.adj[u]) {
                int v = p.xx;
                int i = p.yy;
                int w = edge[i].wgt;
                if(edge[i].cap > edge[i].flw && graph.dst[v] > graph.dst[u] + w) {
                    if(!graph.inq[v]) {
                        graph.inq[v] = 1;
                        q.push(v);
                    }
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    graph.ind[v] = i;
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            int i = graph.ind[v];
            edge[i].flw++;
            edge[i ^ 1].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap = c;
    edge[u][v].flw = 0;
    edge[u][v].wgt = -w;
    edge[v][u].cap = c;
    edge[v][u].flw = c;
    edge[v][u].wgt = w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        int dif = inf;
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap = c;
    edge[u][v].flw = 0;
    edge[u][v].wgt = -w;
    edge[v][u].cap = c;
    edge[v][u].flw = c;
    edge[v][u].wgt = w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    if(n == 350) {
        cout << c << "<<";
    }
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
        if(n == 350)
        cout << " >> " << res << "\n";
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(n == 350) {
                continue;
            }
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap = c;
    edge[u][v].flw = 0;
    edge[u][v].wgt = -w;
    edge[v][u].cap = c;
    edge[v][u].flw = c;
    edge[v][u].wgt = w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    if(n == 350) {
        cout << c << "<<";
    }
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap += c;
    edge[u][v].flw += 0;
    edge[u][v].wgt += -w;
    edge[v][u].cap += c;
    edge[v][u].flw += c;
    edge[v][u].wgt += w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(n == 350) {
            cout << edge[12][13].flw << " <<\n";
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap = c;
    edge[u][v].flw = 0;
    edge[u][v].wgt = -w;
    edge[v][u].cap = c;
    edge[v][u].flw = c;
    edge[v][u].wgt = w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    if(n == 350) {
        cout << c << "<<";
    }
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(n == 350) {
            if(edge[s][0].cap == edge[s][0].flw) {
                cout << s << "-> 0\n";
            }
            for(int i = 0; i < n; ++i) {
                if(edge[i][i + 1].cap == edge[i][i + 1].flw) {
                    cout << i << "->" << i + 1 << "\n";
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        res = max(res, cur);
        if(n == 350)
        cout << " >> " << res << "\n";
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            // if(n == 350) {
            //     continue;
            // }
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 502;
int n, m, c, s;
int x[N];

string t;
string p[N];

struct Edge {
    int cap;
    int flw;
    int wgt;
} edge[N][N];

struct Graph {
    int dst[N];
    int par[N];
    vec <int> adj[N];
} graph;

void input() {
    cin >> n;
    cin >> t;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> p[i];
        cin >> x[i];
    }
    cin >> c;
}

void add_edge(int u, int v, int c, int w) {
    graph.adj[u].pb(v);
    graph.adj[v].pb(u);
    edge[u][v].cap = c;
    edge[u][v].flw = 0;
    edge[u][v].wgt = -w;
    edge[v][u].cap = c;
    edge[v][u].flw = c;
    edge[v][u].wgt = w;
}

int edmonds_karp() {
    int res = 0;
    int cur = 0;
    while(true) {
        fill(graph.dst, graph.dst + N, inf);
        graph.dst[s] = 0;
        queue <int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int v: graph.adj[u]) {
                int w = edge[u][v].wgt;
                if(edge[u][v].cap > edge[u][v].flw && graph.dst[v] > graph.dst[u] + w) {
                    graph.dst[v] = graph.dst[u] + w;
                    graph.par[v] = u;
                    q.push(v);
                }
            }
        }
        if(graph.dst[n] == inf) {
            return res;
        }
        for(int v = n; v != s; ) {
            int u = graph.par[v];
            edge[u][v].flw++;
            edge[v][u].flw--;
            v = u;
        }
        cur -= graph.dst[n];
        if(n == 350) {
            cout << res << ";";
        }
        res = max(res, cur);
    }
    return res;
}

void solve() {
    s = N - 1;
    add_edge(s, 0, c, 0);
    for(int i = 0; i < n; ++i) {
        add_edge(i, i + 1, c, 0);
    }
    for(int i = 0; i < m; ++i) {
        int l = len(p[i]);
        for(int j = 0; j <= n - l; ++j) {
            if(t.substr(j, l) == p[i]) {
                add_edge(j, j + l, 1, x[i]);
            }
        }
    }
    cout << edmonds_karp() << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))
#define FOR(i,j,k) for(int i=j;i<=k;i++)
#define REV(i,j,k) for(int i=j;i>=k;i--)
#define inf         freopen("in.txt", "r", stdin)
#define outf        freopen("out.txt", "w", stdout)
#define valid(nx,ny)  ((nx >= 0) && (nx < n) && (ny >= 0) && (ny < m))
#define MAX 50010

using namespace std;

/// Min-cost Max-flow using SPFA (Shortest Path Faster Algorithm)
/// 0 Based indexed for directed weighted graphs (for undirected graphs, just add two directed edges)

namespace mcmf{
    const int INF = 1LL << 30;

    int dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    void init(int nodes, int source, int sink){
        m = 0, n = nodes;
        s = source, t = sink;
        for (int i = 0; i <= n; i++) last[i] = -1;
    }

    void addEdge(int u, int v, int c, int w){
       // cout << u << ' ' << v << ' ' << c << ' ' << w << endl;
        from[m] = u, adj[m] = v, cap[m] = c, cost[m] = w, next[m] = last[u], last[u] = m++;
        from[m] = v, adj[m] = u, cap[m] = 0, cost[m] = -w, next[m] = last[v], last[v] = m++;
    }

    bool bellman_ford(){
        int i, u, v, e, flag = 1;
        for (i = 0; i < n; i++) to[i] = -1;
        for (i = 0; i < n; i++) dis[i] = INF;

        dis[s] = 0;
        for (i = 0; i < n && flag; i++){
            for (u = 0, flag = 0; u < n; u++){
                for (e = last[u]; e != -1; e = next[e]){
                    v = adj[e];
                    if (cap[e] && dis[v] > (dis[u] + cost[e])){
                        dis[v] = dis[u] + cost[e];
                        to[v] = e;
                        flag = 1;
                    }
                }
            }
        }
        ///assert(i < n); /// Negative cycle found
        return (dis[t] < INF);
    }

    int solve(){
        int maxflow = 0, mincost = 0;

        while (bellman_ford()){
            int aug = INF;
            for (int e = to[t]; e != -1; e = to[from[e]]) aug = min(aug, cap[e]);
            for (int e = to[t]; e != -1; e = to[from[e]]){
                mincost += (aug * cost[e]);
                cap[e] -= aug, cap[e ^ 1] += aug;
            }
            maxflow += aug;
        }
        return mincost;
    }
}

string str, pat[MAX];
int n, m, val[MAX], x;

int main()
{
    ios::sync_with_stdio(false);
    //inf;

    cin >> n >> str >> m;
    FOR(i,0,m-1) cin >> pat[i] >> val[i];
    cin >> x;

    int src = n + 1, des = n + 2;
    mcmf::init(des + 1, src, des);

    mcmf::addEdge(src, 0, x, 0);
    FOR(i,0,n-1) mcmf::addEdge(i, i + 1, x, 0);
    mcmf::addEdge(n, des, x, 0);

    FOR(i,0,m-1)
    {
        int found = -1;
        while(true)
        {
            found = str.find(pat[i], found + 1);
            if(found == string::npos) break;
            else mcmf::addEdge(found, found + pat[i].size(), 1, -val[i]);
        }
    }
    cout <<  -1 * mcmf::solve() << endl;
}


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

#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
#pragma GCC optimize("unroll-loops")

using namespace std;

//using namespace __gnu_pbds;

#define pb push_back
#define F first
#define S second
#define ll long long
#define ld double long
#define ull unsigned long long
#define endl '\n'

const int N = 1e6 + 36;
const ll INF = 1e9 + 7;
const int MOD = 1e9 + 7;

mt19937 gen(19937);

//tree < pair < int, int >, null_type, less < pair < int, int > >, rb_tree_tag, tree_order_statistics_node_update > st;

struct edge {
    int v, to, f, c, cap, obr;
};

vector < edge > E;
int dist[N], bat[N], n, m;
ll a[N];
map < string, int > mp;
string t[N];

void add(vector < edge > &E, int v, int to, int f, int c) {
    edge nw;
    nw.v = v, nw.to = to, nw.f = 0, nw.c = c, nw.cap = f, nw.obr = int(E.size() + 1);
    E.pb(nw);
    nw.v = to, nw.to = v, nw.f = 0, nw.c = -c, nw.cap = 0, nw.obr = int(E.size() - 1);
    E.pb(nw);
}

void tru(int s) {
    dist[s] = 0;
    bool f;
    for (int i(0); i < n; ++i) {
        f = 0;
        for (int j(0); j < int(E.size()); ++j) {
            auto to = E[j];
            if (to.cap == to.f)
                continue;
            if (dist[to.v] != INF && dist[to.v] + to.c < dist[to.to]) {
                dist[to.to] = dist[to.v] + to.c;
                bat[to.to] = j;
                f = 1;
            }
        }
        if (!f) {
            break;
        }
    }
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif // LOCAL
    cin >> n;
    string s;
    cin >> s;
    int m;
    cin >> m;
    for (int i(0); i < m; ++i){
        cin >> t[i] >> a[i];
    }
    int x;
    cin >> x;
    for (int i(0); i < n; ++i){
        string now = "";
        for (int j(i); j < n; ++j){
            now += s[j];
            ++mp[now];
        }
    }
    for (int i(0); i < m; ++i){
        add(E, m, i, min(x, mp[t[i]]), -a[i]);
        add(E, i, m + 1, min(x, mp[t[i]]), 0);
    }
    int flow = 0;
    ll cost = 0;
    n = m + 2;
    while (true) {
        for (int i(0); i < n; ++i) {
            dist[i] = INF;
        }
        tru(n - 2);
        if (dist[n - 1] == INF)
            break;
        int addflow = INF;
        for (int v(n - 1); v != n - 2; v = E[bat[v]].v) {
            addflow = min(addflow, E[bat[v]].cap - E[bat[v]].f);
        }
//        if (flow + addflow > k){
//            addflow = min(k - flow);
//        }
        ll now = 0;
        for (int v(n - 1); v != n - 2; v = E[bat[v]].v) {
            E[bat[v]].f += addflow;
            E[E[bat[v]].obr].f -= addflow;
            now += 1ll * E[bat[v]].c * addflow;
        }
        if (now > 0){
            break;
        }
        cost += now;
        flow += addflow;
    }
    //cout << flow << endl;
    cout << abs(cost) << endl;
    return 0;
}

/* Thu Nov 21 2019 20:52:45 GMT+0300 (MSK) */


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

#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
#pragma GCC optimize("unroll-loops")

using namespace std;

//using namespace __gnu_pbds;

#define pb push_back
#define F first
#define S second
#define ll long long
#define ld double long
#define ull unsigned long long
#define endl '\n'

const int N = 1e6 + 36;
const ll INF = 1e9 + 7;
const int MOD = 1e9 + 7;

mt19937 gen(19937);

//tree < pair < int, int >, null_type, less < pair < int, int > >, rb_tree_tag, tree_order_statistics_node_update > st;

struct edge {
    int v, to, f, c, cap, obr;
};

vector < edge > E;
int dist[N], bat[N], n, m;
ll a[N];
map < string, int > mp;
string t[N];

void add(vector < edge > &E, int v, int to, int f, int c) {
    edge nw;
    nw.v = v, nw.to = to, nw.f = 0, nw.c = c, nw.cap = f, nw.obr = int(E.size() + 1);
    E.pb(nw);
    nw.v = to, nw.to = v, nw.f = 0, nw.c = -c, nw.cap = 0, nw.obr = int(E.size() - 1);
    E.pb(nw);
}

void tru(int s) {
    dist[s] = 0;
    bool f;
    for (int i(0); i < n; ++i) {
        f = 0;
        for (int j(0); j < int(E.size()); ++j) {
            auto to = E[j];
            if (to.cap == to.f)
                continue;
            if (dist[to.v] != INF && dist[to.v] + to.c < dist[to.to]) {
                dist[to.to] = dist[to.v] + to.c;
                bat[to.to] = j;
                f = 1;
            }
        }
        if (!f) {
            break;
        }
    }
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif // LOCAL
    cin >> n;
    string s;
    cin >> s;
    int m;
    cin >> m;
    for (int i(0); i < m; ++i){
        cin >> t[i] >> a[i];
    }
    add(E, n, 0, INF, 0);
    for (int i(0); i < n; ++i){
        if (i == n - 1){
            add(E, i, n + 1, INF, 0);
        } else {
            add(E, i, i + 1, INF, 0);
        }
        for (int j(0); j < m; ++j){
            if (i + int(t[j].size()) <= n && s.substr(i, int(t[j].size())) == t[j]){
                int nxt = i + int(t[j].size());
                if (nxt == n){
                    ++nxt;
                }
                add(E, i, nxt, 1, -a[j]);
            }
        }
    }
//    for (auto to:E){
//        cout << to.v << ' ' << to.to << ' ' << to.cap << ' ' << to.c << endl;
//    }

    int x;
    cin >> x;
    ll cost = 0, flow = 0;
    n += 2;
    while (x--) {
        for (int i(0); i < n; ++i) {
            dist[i] = INF;
        }
        tru(n - 2);
        if (dist[n - 1] == INF)
            break;
        int addflow = INF;
        for (int v(n - 1); v != n - 2; v = E[bat[v]].v) {
            addflow = min(addflow, E[bat[v]].cap - E[bat[v]].f);

        }
//        if (flow + addflow > k){
//            addflow = min(k - flow);
//        }
        ll now = 0;
        for (int v(n - 1); v != n - 2; v = E[bat[v]].v) {
            E[bat[v]].f += addflow;
            E[E[bat[v]].obr].f -= addflow;
            now += 1ll * E[bat[v]].c * addflow;
        }
        if (now > 0){
            break;
        }
        cost += now;
        flow += addflow;
    }
    //cout << flow << endl;
    cout << abs(cost) << endl;
    return 0;
}

/* Wed Nov 27 2019 19:03:58 GMT+0300 (MSK) */


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <cmath>
#include <bitset>
#include <iomanip>
#include <queue>
#include <stack>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <unordered_map>

#define int ll
#define fs first
#define sd second
#define mp make_pair
#define pb push_back
#define sz(x) int((x).size())
#define all(x) begin(x), end(x)
#define OUT(x) { cout << x; exit(0); }
//#define resize do_not_use_resize
using namespace std;
typedef double db;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
const db eps = 1e-9;
const db pi = acos(-1.0);
const db dinf = 1e250;
const ll INF = (ll)(2e18);
const int inf = (int)(1e9 + 7);
const int mod = 1e9 + 7;
const int MAXN = 2*1e5 + 5;
//------------------------------------------//

int n, x;
struct edge {
  int fr, to, cap, cost, flow;
};

vector<edge> ed;

void add_ed(int fr, int to, int cap, int cost) {
  ed.pb({fr, to, cap, cost, 0});
  ed.pb({to, fr, 0, -cost, 0});
}

vector<int> d, pr, minfl;
int s, t;

int fb() {
  d[s] = 0;
  bool fl = 1;
  while (fl) {
    fl = 0;
    for (int i = 0; i < ed.size(); ++i) {
      int fr = ed[i].fr, to = ed[i].to;
      int c = ed[i].cost;
      if (d[fr] != inf && d[fr] + c < d[to] && ed[i].cap > ed[i].flow) {
        d[to] = d[fr] + c;
        pr[to] = i;
        minfl[to] = min(minfl[fr], ed[i].cap - ed[i].flow);
        fl = 1;
      }
    }
  }
  if (d[t] == inf)
    return inf;
  return d[t] * min(minfl[t], x);
}

int32_t main()
{
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cin.tie(0);

  //--------------------------------//

  cin >> n;
  string str; cin >> str;
  int m; cin >> m;
  vector<string> w(m);
  vector<int> p(m);
  for (int i = 0; i < m; ++i) {
    cin >> w[i] >> p[i];
  }
  cin >> x;

  for (int i = 0; i < n+1; ++i) {
    add_ed(i, i + 1, inf, 0);
  }

  for (int i = 0; i < m; ++i) {
    string st = w[i] + str;
    int sz = st.size();
    vector<int> z(sz, 0);
    int l = 0, r = 0;
    for (int j = 1; j < sz; ++j) {
      if (j <= r) z[j] = min(z[j - l], r - j + 1);
      for (; j + z[j] < sz && st[z[j]] == st[j + z[j]]; ++z[j]);
      if (j + z[j] - 1 > r) {
        l = j;
        r = j + z[j] - 1;
      }
    }
    int szw = w[i].size();
    for (int j = szw; j < sz; ++j) {
      if (z[j] >= szw) {
        add_ed(j - szw + 1, j + 1, 1, -p[i]);
      }
    }
  }
  n += 2;
  s = 0, t = n - 1;
  int ans = 0;
  while (x > 0) {
    d.assign(n, inf);
    pr.assign(n, -1);
    minfl.assign(n, inf);
    int a = fb();
    if (a == inf) break;
    ans += a;
    x -= minfl[t];
    int v = t;
    while (true) {
      if (v == s) break;
      ed[pr[v]].flow += minfl[t];
      ed[pr[v] ^ 1].flow -= minfl[t];
      v = ed[pr[v]].fr;
    }
  }
  cout << -ans << endl;
  return 0;
}


//Be Name Khoda
/*
tane adami sharifast be jane adamiat
na hamin lebase zibast neshane adamiat
agar adami be cheshmasto dahano goosho bini
che miane naghshe divaro miane adamiat
khoro khabo khashmo shahvat shaghab asto jahlo zolmat
hayavan khabar nadarad ze jahane adamiat
be haghighat adami bash vagarna morgh bashad
ke hami sokhan begooyad be zabane adamiat
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef long long LL;
typedef LL ll;
typedef double ld;
typedef string str;
typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef stringstream strs;

#define X first
#define Y second
#define PB push_back
#define For(i,a,b) for (ll i=a;i<b;++i)
#define Ford(i,a,b) for (ll i=a;i>=b;--i)
#define smax(a,b) a=max(a,b)
#define smin(a,b) a=min(a,b)
#define SZ(a) ((ll)a.size())
#define ER(a) cout << #a << ' ' << a << endl
#define LB(a,n,x) (lower_bound(a,(a)+(n),x)-(a))
#define RET(x) { cout << x; exit(0); }
#define MKP make_pair
#define RETD(x) { cout << fixed << setprecision(12) << x << ' '; } //exit(0); }
#define GEI(x) scanf("%d",&x)
#define GEL(x) scanf("%lld",&x)
#define ALL(x) x.begin(),x.end()
const ll M=2e5+5,LG=32,SM=600+5,inf=1e18+5;
ll mod=1e9+7;
LL pw(LL a,ll n) { return (n==0?1:pw(a*a%mod,n/2)*(n%2?a:1)%mod); }
#define MOK(x) while (x>=mod) x-=mod;

ll from[M],head[M],pre[M],to[M],cap[M];
ll cst[M];
ll tnod,cnt;
ll x;

void add(ll u,ll v,ll w,ld t)
{
  from[cnt]=u;cap[cnt]=w;cst[cnt]=t;to[cnt]=v;
  pre[cnt]=head[u];head[u]=cnt++;
  from[cnt]=v;cap[cnt]=0;cst[cnt]=-t;to[cnt]=u;
  pre[cnt]=head[v];head[v]=cnt++;
}

ll h[M];
ll fl[M],par[M];
ll flow;
ll cost;

ll spfa()
{
  fill(h,h+tnod+1,inf);
  h[0]=0;
  fl[0]=inf;
  fl[tnod]=0;
  queue<ll> qu;
  qu.push(0);
  while (SZ(qu)){
    ll x=qu.front();
    //ER(x);
    qu.pop();
    for (ll i=head[x];i!=-1;i=pre[i]){
      if (!cap[i] || h[to[i]]<=h[x]+cst[i]) continue;
      par[to[i]]=i;
      h[to[i]]=h[x]+cst[i];
      fl[to[i]]=min(fl[x],cap[i]);
      qu.push(to[i]);
    }
  }
  ll s=tnod,r=min(fl[tnod],x);
  if (r==0) return 0;
  flow+=r;
  while (s)
    {
      ll i=par[s];
      cap[i]-=r;
      cap[i^1]+=r;
      cost+=r*cst[i];
      s=from[i];
    }
  return 1;
}

ll t[M];
pll po[M];

ll p2(ll x){
  return x*x;
}

int main()
{
    memset(head,-1,sizeof head);
    ll n;
    cin >> n;
    str s;
    cin >> s;
    ll m;
    cin >> m;
    For(i,1,n+1){
      add(i-1,i,inf,0);
    }
    For(rep,0,m){
      str f;
      cin >> f;
      ll p;
      cin >> p;
      For(i,0,n-SZ(f)+1){
	bool ok=1;
	For(j,0,SZ(f)){
	  if (s[i+j]!=f[j]){
	    ok=0;
	    break;
	  }
	}
	if (ok){
	  //ER(i);ER(i+SZ(f));ER(1);ER(p);
	  add(i,i+SZ(f),1,-p);
	}
      }
    }
    cin >> x;
    tnod=n;
    while(flow<x){
      spfa();
      //ER(cost);
      //ER(flow);
    }
    cout << -cost << '\n';
}


//Be Name Khoda
/*
tane adami sharifast be jane adamiat
na hamin lebase zibast neshane adamiat
agar adami be cheshmasto dahano goosho bini
che miane naghshe divaro miane adamiat
khoro khabo khashmo shahvat shaghab asto jahlo zolmat
hayavan khabar nadarad ze jahane adamiat
be haghighat adami bash vagarna morgh bashad
ke hami sokhan begooyad be zabane adamiat
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef long long LL;
typedef LL ll;
typedef double ld;
typedef string str;
typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef stringstream strs;

#define X first
#define Y second
#define PB push_back
#define For(i,a,b) for (ll i=a;i<b;++i)
#define Ford(i,a,b) for (ll i=a;i>=b;--i)
#define smax(a,b) a=max(a,b)
#define smin(a,b) a=min(a,b)
#define SZ(a) ((ll)a.size())
#define ER(a) cout << #a << ' ' << a << endl
#define LB(a,n,x) (lower_bound(a,(a)+(n),x)-(a))
#define RET(x) { cout << x; exit(0); }
#define MKP make_pair
#define RETD(x) { cout << fixed << setprecision(12) << x << ' '; } //exit(0); }
#define GEI(x) scanf("%d",&x)
#define GEL(x) scanf("%lld",&x)
#define ALL(x) x.begin(),x.end()
const ll M=2e5+5,LG=32,SM=600+5,inf=1e18+5;
ll mod=1e9+7;
LL pw(LL a,ll n) { return (n==0?1:pw(a*a%mod,n/2)*(n%2?a:1)%mod); }
#define MOK(x) while (x>=mod) x-=mod;

ll from[M],head[M],pre[M],to[M],cap[M];
ll cst[M];
ll tnod,cnt;
ll x;

void add(ll u,ll v,ll w,ld t)
{
  from[cnt]=u;cap[cnt]=w;cst[cnt]=t;to[cnt]=v;
  pre[cnt]=head[u];head[u]=cnt++;
  from[cnt]=v;cap[cnt]=0;cst[cnt]=-t;to[cnt]=u;
  pre[cnt]=head[v];head[v]=cnt++;
}

ll h[M];
ll fl[M],par[M];
ll flow;
ll cost;

ll spfa()
{
  fill(h,h+tnod+1,inf);
  h[0]=0;
  fl[0]=inf;
  fl[tnod]=0;
  queue<ll> qu;
  qu.push(0);
  while (SZ(qu)){
    ll x=qu.front();
    //ER(x);
    qu.pop();
    for (ll i=head[x];i!=-1;i=pre[i]){
      if (!cap[i] || h[to[i]]<=h[x]+cst[i]) continue;
      par[to[i]]=i;
      h[to[i]]=h[x]+cst[i];
      fl[to[i]]=min(fl[x],cap[i]);
      qu.push(to[i]);
    }
  }
  ll s=tnod,r=min(fl[tnod],x);
  if (r==0) return 0;
  flow+=r;
  while (s)
    {
      ll i=par[s];
      cap[i]-=r;
      cap[i^1]+=r;
      cost+=r*cst[i];
      s=from[i];
    }
  return 1;
}

ll t[M];
pll po[M];

ll p2(ll x){
  return x*x;
}

int main()
{
    memset(head,-1,sizeof head);
    ll n;
    cin >> n;
    str s;
    cin >> s;
    ll m;
    cin >> m;
    For(i,1,n+1){
      add(i-1,i,inf,0);
    }
    For(rep,0,m){
      str f;
      cin >> f;
      ll p;
      cin >> p;
      For(i,0,n-SZ(f)+1){
	bool ok=1;
	For(j,0,SZ(f)){
	  if (s[i+j]!=f[j]){
	    ok=0;
	    break;
	  }
	}
	if (ok){
	  ER(i);ER(i+SZ(f));ER(1);ER(p);
	  add(i,i+SZ(f),1,-p);
	}
      }
    }
    cin >> x;
    tnod=n;
    while(flow<x){
      spfa();
      //ER(cost);
      //ER(flow);
    }
    cout << -cost << '\n';
}


//Be Name Khoda
/*
tane adami sharifast be jane adamiat
na hamin lebase zibast neshane adamiat
agar adami be cheshmasto dahano goosho bini
che miane naghshe divaro miane adamiat
khoro khabo khashmo shahvat shaghab asto jahlo zolmat
hayavan khabar nadarad ze jahane adamiat
be haghighat adami bash vagarna morgh bashad
ke hami sokhan begooyad be zabane adamiat
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef long long LL;
typedef LL ll;
typedef double ld;
typedef string str;
typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef stringstream strs;

#define X first
#define Y second
#define PB push_back
#define For(i,a,b) for (ll i=a;i<b;++i)
#define Ford(i,a,b) for (ll i=a;i>=b;--i)
#define smax(a,b) a=max(a,b)
#define smin(a,b) a=min(a,b)
#define SZ(a) ((ll)a.size())
#define ER(a) cout << #a << ' ' << a << endl
#define LB(a,n,x) (lower_bound(a,(a)+(n),x)-(a))
#define RET(x) { cout << x; exit(0); }
#define MKP make_pair
#define RETD(x) { cout << fixed << setprecision(12) << x << ' '; } //exit(0); }
#define GEI(x) scanf("%d",&x)
#define GEL(x) scanf("%lld",&x)
#define ALL(x) x.begin(),x.end()
const ll M=2e5+5,LG=32,SM=600+5,inf=1e18+5;
ll mod=1e9+7;
LL pw(LL a,ll n) { return (n==0?1:pw(a*a%mod,n/2)*(n%2?a:1)%mod); }
#define MOK(x) while (x>=mod) x-=mod;

ll from[M],head[M],pre[M],to[M],cap[M];
ll cst[M];
ll tnod,cnt;
ll x;

void add(ll u,ll v,ll w,ld t)
{
  from[cnt]=u;cap[cnt]=w;cst[cnt]=t;to[cnt]=v;
  pre[cnt]=head[u];head[u]=cnt++;
  from[cnt]=v;cap[cnt]=0;cst[cnt]=-t;to[cnt]=u;
  pre[cnt]=head[v];head[v]=cnt++;
}

ll h[M];
ll fl[M],par[M];
ll flow;
ll cost;

ll spfa()
{
  fill(h,h+tnod+1,inf);
  h[0]=0;
  fl[0]=inf;
  fl[tnod]=0;
  queue<ll> qu;
  qu.push(0);
  while (SZ(qu)){
    ll x=qu.front();
    //ER(x);
    qu.pop();
    for (ll i=head[x];i!=-1;i=pre[i]){
      if (!cap[i] || h[to[i]]<=h[x]+cst[i]) continue;
      par[to[i]]=i;
      h[to[i]]=h[x]+cst[i];
      fl[to[i]]=min(fl[x],cap[i]);
      qu.push(to[i]);
    }
  }
  ll s=tnod,r=min(fl[tnod],x);
  if (r==0) return 0;
  flow+=r;
  while (s)
    {
      ll i=par[s];
      cap[i]-=r;
      cap[i^1]+=r;
      cost+=r*cst[i];
      s=from[i];
    }
  return 1;
}

ll t[M];
pll po[M];

ll p2(ll x){
  return x*x;
}

int main()
{
    memset(head,-1,sizeof head);
    ll n;
    cin >> n;
    str s;
    cin >> s;
    ll m;
    cin >> m;
    For(i,1,n+1){
      add(i-1,i,inf,0);
    }
    For(rep,0,m){
      str f;
      cin >> f;
      ll p;
      cin >> p;
      For(i,0,n-SZ(f)+1){
	bool ok=1;
	For(j,0,SZ(f)){
	  if (s[i+j]!=f[j]){
	    ok=0;
	    break;
	  }
	}
	if (ok){
	  ER(i);ER(i+SZ(f));ER(1);ER(p);
	  add(i,i+SZ(f),1,-p);
	}
      }
    }
    cin >> x;
    tnod=n;
    while(flow<x){
      spfa();
      ER(cost);
      ER(flow);
    }
    cout << -cost << '\n';
}


#include<bits/stdc++.h>
using namespace std;
const int N=505,E=200005;
int n,m,cnt[N],x;
char c[N],b[N];
int head[N],Next[E],adj[E],cap[E],cost[E];
int q[N*10000],pre[N],vis[N],now[N];
int flow,S,T,num=1;
long long d[N];
void addedge(int u,int v,int f,int w)
{
	//cout<<u<<' '<<v<<' '<<f<<' '<<w<<endl;
	Next[++num]=head[u],head[u]=num,adj[num]=v,cap[num]=f,cost[num]=w;
	Next[++num]=head[v],head[v]=num,adj[num]=u,cap[num]=0,cost[num]=-w;
}
bool SPFA()
{
	int i,l,r;
	q[l=r=1]=S;
	vis[S]=1;
	memset(d,0x7f,sizeof(d));
	d[S]=0;
	while(l<=r)
	{
		for(i=head[q[l]];i;i=Next[i])
			if(cap[i]&&d[adj[i]]>d[q[l]]+cost[i])
			{
				d[adj[i]]=d[q[l]]+cost[i];
				if(!vis[adj[i]])
				{
					vis[adj[i]]=1;
					q[++r]=adj[i];
				}
			}
		vis[q[l]]=0;
		++l;
	}
	return (d[T]<1<<30);
}
bool dfs(int i,int f)
{
	if(i==T)
	{
		flow=f;
		return true;
	}
	if(vis[i])
		return false;
	int j;
	vis[i]=1;
	for(j=now[i];j;now[i]=j=Next[j])
		if(cap[j]&&d[adj[j]]==d[i]+cost[j]&&dfs(adj[j],min(f,cap[j])))
		{
			cap[j]-=flow;
			cap[j^1]+=flow;
			vis[i]=0;
			return true;
		}
	vis[i]=0;
	return false;
}
long long ans,ansf;
void minmax()
{
	while(SPFA())
	{
		memcpy(now,head,sizeof(now));
		while(dfs(S,2147483646))
			ans+=flow*d[T],ansf+=flow;
	}
}
int i,j,k;
long long s=0;
int main()
{
	scanf("%d %d",&n,&m);
	scanf("%s",c+1);
	while(m--)
	{
		int q;
		scanf("%s",b);
		scanf("%d",&q);
		for(j=1;j<=n;++j)
		{
			for(k=0;b[k]&&c[j+k]==b[k];++k);
			if(!b[k])
			{
				//cout<<j<<' '<<k<<endl;
				addedge(j,j+k,1,q);
				++cnt[j];
				--cnt[j+k];
				s+=q;
			}
		}
	}
	scanf("%d",&x);
	for(i=1;i<=n;++i)
		addedge(i,i+1,x,0);
	S=0;
	T=n+2;
	for(j=1;j<=n+1;++j)
	{
		if(cnt[j]>0)
			addedge(S,j,cnt[j],0);
		if(cnt[j]<0)
			addedge(j,T,-cnt[j],0);
	}
	minmax();
	cout<<s-ans;
}


#include<bits/stdc++.h>
using namespace std;
const int N=505,E=200005;
int n,m,cnt[N],x;
char c[N],b[N];
int head[N],Next[E],adj[E],cap[E],cost[E];
int q[N*10000],pre[N],vis[N],now[N];
int flow,S,T,num=1;
long long d[N];
void addedge(int u,int v,int f,int w)
{
	//cout<<u<<' '<<v<<' '<<f<<' '<<w<<endl;
	Next[++num]=head[u],head[u]=num,adj[num]=v,cap[num]=f,cost[num]=w;
	Next[++num]=head[v],head[v]=num,adj[num]=u,cap[num]=0,cost[num]=-w;
}
bool SPFA()
{
	int i,l,r;
	q[l=r=1]=S;
	vis[S]=1;
	memset(d,0x7f,sizeof(d));
	d[S]=0;
	while(l<=r)
	{
		for(i=head[q[l]];i;i=Next[i])
			if(cap[i]&&d[adj[i]]>d[q[l]]+cost[i])
			{
				d[adj[i]]=d[q[l]]+cost[i];
				if(!vis[adj[i]])
				{
					vis[adj[i]]=1;
					q[++r]=adj[i];
				}
			}
		vis[q[l]]=0;
		++l;
	}
	return (d[T]<1<<30);
}
bool dfs(int i,int f)
{
	if(i==T)
	{
		flow=f;
		return true;
	}
	if(vis[i])
		return false;
	int j;
	vis[i]=1;
	for(j=now[i];j;now[i]=j=Next[j])
		if(cap[j]&&d[adj[j]]==d[i]+cost[j]&&dfs(adj[j],min(f,cap[j])))
		{
			cap[j]-=flow;
			cap[j^1]+=flow;
			vis[i]=0;
			return true;
		}
	vis[i]=0;
	return false;
}
long long ans,ansf;
void minmax()
{
	while(SPFA())
	{
		memcpy(now,head,sizeof(now));
		while(dfs(S,2147483646))
			ans+=flow*d[T],ansf+=flow;
	}
}
int i,j,k;
long long s=0;
int main()
{
	scanf("%d",&n);
	scanf("%s",c+1);
	scanf("%d",&m);
	while(m--)
	{
		int q;
		scanf("%s",b);
		scanf("%d",&q);
		for(j=1;j<=n;++j)
		{
			for(k=0;b[k]&&c[j+k]==b[k];++k);
			if(!b[k])
			{
				//cout<<j<<' '<<k<<endl;
				addedge(j,j+k,1,q);
				++cnt[j];
				--cnt[j+k];
				s+=q;
			}
		}
	}
	scanf("%d",&x);
	for(i=1;i<=n;++i)
		addedge(i,i+1,x,0);
	S=0;
	T=n+2;
	for(j=1;j<=n+1;++j)
	{
		if(cnt[j]>0)
			addedge(S,j,cnt[j],0);
		if(cnt[j]<0)
			addedge(j,T,-cnt[j],0);
	}
	minmax();
	cout<<s-ans;
}


//THIS IS MY DESIGN

#include<bits/stdc++.h>
#define pb(a)           push_back(a)
#define mp(a,b)         make_pair(a,b)
#define pii             pair<int,int>
#define pll             pair<L,L>
#define ff              first
#define ss              second
#define SIZE            100010
#define write           freopen("output.txt","w",stdout)
#define read            freopen("input.txt","r",stdin)
#define eps             1e-9
#define MOD             1000000007
#define ALL(a)          a.begin(),a.end()
#define CLEAR(a)        memset(a,0,sizeof(a))
#define SET(a)          memset(a,-1,sizeof(a))
using namespace std;
typedef long long int L;
int dx[]={1,-1,0,0,1,1,-1,-1};
int dy[]={0,0,1,-1,-1,1,1,-1};
inline int nxt(){int a;scanf("%d",&a);return a;}
inline L NXT(){L a;scanf("%lld",&a);return a;}
template <typename T> string NumberToString ( T Number ) { ostringstream ss; ss << Number; return ss.str(); }
template <class T> inline T bigmod(T p,T e,T m){T ret = 1;
for(; e > 0; e >>= 1){
    if(e & 1) ret = (ret * p) % m;p = (p * p) % m;
} return (T)ret;}
template < class T> inline T biton(T n,T pos){return n |((T)1<<pos);}
template < class T> inline T bitoff(T n,T pos){return n & ~((T)1<<pos);}
template < class T> inline T bitcheck(T n,T pos){return (bool)(n & ((T)1<<pos));}
template < class T> inline T gcd(T a, T b){while(b){a%=b;swap(a,b);}return a;}
#ifdef lucifer
     #define debug(args...) {cerr<<"*: "; dbg,args; cerr<<endl;}
#else
    #define debug(args...)  // Just strip off all debug tokens
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

const L INF=(L)1<<60;
struct Edge{
	L from,to,cap,flow,cost;
	Edge(int from,int to,int cap,int flow,int cost):from(from),to(to),cap(cap),flow(flow),cost(cost) {}
};
const int N = 1010;
namespace mcmf{
	int n,m,s,t;
	vector<Edge> edges;
	vector<L> G[N];
	bool inq[N];
	L d[N],p[N],a[N];                     /// N = Size of nodes in flow network
	void init(int src,int sink,int node)
	{
		n=node;
		s= src;
		t = sink;
		edges.clear();
		for(int i=0;i<=n;++i) G[i].clear();
	}
	void addEdge(int from,int to,L cap,L cost)
	{
		edges.push_back(Edge(from,to,cap,0,cost));
		edges.push_back(Edge(to,from,0,0,-cost));
		m=edges.size();
		G[from].push_back(m-2);
		G[to].push_back(m-1);
	}
	bool spfa(L &flow,L& cost)
	{
		for(int i=0;i<=n;++i) d[i]=INF,inq[i]=0;
		queue<int> que;
		que.push(s);
		inq[s]=1;d[s]=0;p[s]=0;a[s]=INF;
		while(!que.empty())
		{
			int x=que.front();que.pop();
			inq[x]=0;
			for(int i=0;i<G[x].size();++i)
			{
				Edge &e=edges[G[x][i]];
				if(e.cap>e.flow && d[e.to]>d[x]+e.cost)
				{
					d[e.to]=d[x]+e.cost;
					p[e.to]=G[x][i];
					a[e.to]=min(a[x],e.cap-e.flow);
					if(!inq[e.to]) inq[e.to]=1,que.push(e.to);
				}
			}
		}
		if(d[t]==INF) return 0;
		flow+=a[t];
		cost+=d[t];    /// multiply by d[t]*a[t] if per unit cost is given.
		int u=t;
		while(u!=s)
		{
			edges[p[u]].flow+=a[t];
			edges[p[u]^1].flow-=a[t];
			u=edges[p[u]].from;
		}
		return 1;
	}
	pll solve()
	{
		L flow=0,cost=0;
		while(spfa(flow,cost));
		return make_pair(cost,flow);
	}
}

int main()
{
    #ifdef lucifer
        read;
        //write;
    #endif
    ios_base::sync_with_stdio(0);
    int n;
    string s;
    cin>>n>>s;
    s= "#"+s;
    mcmf::init(0,n+1,n+3);
    int x;
    cin>>x;
    for(int i = 0 ; i<x;i++){
        string t;
        int  p ;
        cin>>t>>p;
        for(int j = 1 ; j<s.size();j++){
            if( s.substr( j,t.size()) ==t){
                mcmf::addEdge(j,j+t.size(),1,-p);
            }
        }
    }
    int cost;
    cin>>cost;
    for(int i = 0 ; i<=n;i++){
        mcmf::addEdge(i,i+1,cost,0);

    }
    long flow =0 ,c = 0;
    pll ans= mcmf::solve();
    cout<<-ans.ff <<endl;
    return 0;
}


#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
using namespace std;
template<class t> inline t read(t &x){
	char c=getchar();bool f=0;x=0;
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	if(f) x=-x;return x;
}
template<class t,class ...A> inline void read(t &x,A &...a){
	read(x);read(a...);
}
template<class t> inline void write(t x){
	if(x<0) putchar('-'),write(-x);
	else{if(x>9) write(x/10);putchar('0'+x%10);}
}

const int N=505,M=5e5+5;
int h[N],en=1,n,m,mc,mf,dis[N];
char s[N],t[N];
bool v[N];

struct edge{
	int n,v,f,w;
}e[M<<1];

void add(int x,int y,int f,int w){
	e[++en]=(edge){h[x],y,f,w};
	h[x]=en;
}

void exadd(int x,int y,int f,int w){
	add(x,y,f,w);
	add(y,x,0,-w);
}

bool spfa(int s,int aim){
	queue<int> q;
	q.push(s);
	memset(v,0,sizeof v);
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	v[s]=1;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		v[x]=0;
		for(int i=h[x];i;i=e[i].n){
			int y=e[i].v;
			if(dis[x]+e[i].w<dis[y]&&e[i].f){
				dis[y]=dis[x]+e[i].w;
				if(!v[y]){
					q.push(y);
					v[y]=1;
				}
			}
		}
	}
	return dis[aim]^0x3f3f3f3f;
}

int dfs(int x,int flow,int aim){
	if(x==aim) return flow;
	int rest=flow;
	v[x]=1;
	for(int i=h[x];i&&rest;i=e[i].n){
		int y=e[i].v;
		if(!v[y]&&dis[y]==dis[x]+e[i].w&&e[i].f){
			int tp=dfs(y,min(rest,e[i].f),aim);
			if(!tp) dis[y]=0x3f3f3f3f;
			rest-=tp;
			mc+=tp*e[i].w;
			e[i].f-=tp;
			e[i^1].f+=tp;
		}
	}
	v[x]=0;
	return flow-rest;
}

void mcmf(int s,int t){
	mc=mf=0;
	while(spfa(s,t)) mf+=dfs(s,INT_MAX,t);
}

signed main(){
	read(n);scanf("%s",s+1);read(m);
	while(m--){
		int nm,w;
		scanf("%s",t+1);nm=strlen(t+1);read(w);
		for(int i=1;i+nm-1<=n;i++){
			bool flag=1;
			for(int j=1;j<=nm;j++) if(s[i+j-1]!=t[j]) {flag=0;break;}
			if(flag) exadd(i,i+nm,1,-w);
		}
	}
	int k;
	read(k);
	for(int i=0;i<=n;i++) exadd(i,i+1,k,0);
	mcmf(0,n+1);
	write(-mc);
}


/*
 © 2020-04-13 09:35:01 crystaalroo all Rights Reserved
*/

#include <bits/stdc++.h>

#define f first
#define s second
#define fore(i,a,b) for(int i = (a), ThxMK = (b); i < ThxMK; ++i)
#define pb push_back
#define all(s) begin(s), end(s)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define sz(s) int(s.size())
#define ENDL '\n'
using namespace std;
typedef long double ld;
typedef pair<int,int> ii;
typedef long long lli;
typedef lli tf;
const tf INF=1e18;
struct MCF{
	int n;
	vector<tf> prio,curflow,prevedge,prevnode,pot;
	priority_queue<lli,vector<lli>,greater<lli>> q;
	struct edge{int to, rev; tf f, cap, cost;};
	vector<vector<edge>> g;
	MCF(int n):n(n),prio(n),curflow(n),prevedge(n),prevnode(n),pot(n),g(n){}
	void add(int s, int t, tf cap, tf cost) {
		g[s].pb((edge){t,sz(g[t]),0,cap,cost});
		g[t].pb((edge){s,sz(g[s])-1,0,0,-cost});
	}
	pair<tf,tf> get_flow(int s, int t) {
		tf flow=0, flowcost=0;
		while(1){
			q.push(s);
			fill(all(prio),INF);
			prio[s]=0; curflow[s]=INF;
			while(!q.empty()) {
				lli cur=q.top();
				int d=cur>>32, u=cur;
				q.pop();
				if(d!=prio[u]) continue;
				for(int i=0; i<sz(g[u]); ++i) {
					edge &e=g[u][i];
					int v=e.to;
					if(e.cap<=e.f) continue;
					tf nprio=prio[u]+e.cost+pot[u]-pot[v];
					if(prio[v]>nprio) {
						prio[v]=nprio;
						q.push(((lli)nprio<<32)+v);
						prevnode[v]=u; prevedge[v]=i;
						curflow[v]=min(curflow[u], e.cap-e.f);
					}
				}
			}
			if(prio[t]==INF) break;
			fore(i,0,n) pot[i]+=prio[i];
			tf df=min(curflow[t], INF-flow);
			flow+=df;
			for(int v=t; v!=s; v=prevnode[v]) {
				edge &e=g[prevnode[v]][prevedge[v]];
				e.f+=df; g[v][e.rev].f-=df;
				flowcost+=df*e.cost;
			}
		}
		return {flow,flowcost};
	}
};
int main(){_
  int n,m,x; cin>>n;
  string s; cin>>s>>m;
  MCF D(n+5);
  vector<pair<string,lli>>v(m);
  fore(i,0,m)cin>>v[i].f>>v[i].s;
  cin>>x;
  fore(i,0,m)
    fore(j,0,n-sz(v[i].f)+1){
      bool ok = 1;
      for(int k = 0; k<sz(v[i].f) and ok;k++)ok&=(s[j+k]==v[i].f[k]);
      if(ok)D.add(j,j+sz(v[i].f),1,-v[i].s);
    }
    fore(i,0,n)D.add(i,i+1,x,0);
    D.add(n+1,0,x,0);
    lli res = D.get_flow(n+1,n).s; cout<<-res<<ENDL;
}


#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
#define println(a) printf("%lld\n",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
#define erep(i,u) for(int i=head[u];~i;i=nxt[i])
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int MAXN = 2e5+11;
const ll oo = 0x3f3f3f3f3f3f3f3f;
const ll ooo= 0x3f3f3f3f;
ll read(){
    ll x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int to[MAXN<<1],nxt[MAXN<<1],from[MAXN<<1];
ll cost[MAXN<<1],cap[MAXN<<1],flow[MAXN<<1];
int head[MAXN],tot;
int n,m,s,t;
bool vis[MAXN];
ll pre[MAXN],dis[MAXN];
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void add(int u,int v,ll c,ll w){
    from[tot]=u;
    to[tot]=v;
    cap[tot]=c;
    flow[tot]=0;
    cost[tot]=w;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    from[tot]=u;
    to[tot]=v;
    cap[tot]=0;
    flow[tot]=0;
    cost[tot]=-w;
    nxt[tot]=head[u];
    head[u]=tot++;
}
struct QUEUE{
    int que[MAXN];
    int front,rear;
    void init(){front=rear=0;}
    void push(int x){que[rear++]=x;}
    int pop(){return que[front++];}
    bool empty(){return front==rear;}
}que;
bool spfa(){
    que.init();
    memset(vis,0,sizeof vis);
    memset(pre,-1,sizeof pre);
    memset(dis,0x3f,sizeof dis);
    que.push(s);
    vis[s]=1;dis[s]=0;
    while(!que.empty()){
        int u=que.pop();vis[u]=0;
        for(int i = head[u]; ~i; i = nxt[i]){
            ll v=to[i],c=cap[i],f=flow[i],w=cost[i];
            if(c>f&&dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                pre[v]=i;
                if(!vis[v]){
                    que.push(v);
                    vis[v]=1;
                }
            }
        }
    }
    if(dis[t]==oo) return 0;
    else return 1;
}

P mcmf(){
    ll mc=0,mf=0;
    while(spfa()){
        ll tf=oo+1;
        for(int i = pre[t]; ~i; i = pre[to[i^1]]){
            tf=min(tf,cap[i]-flow[i]);
        }
        mf+=tf;
        for(int i = pre[t]; ~i; i = pre[to[i^1]]){
            flow[i]+=tf;
            flow[i^1]-=tf;
        }
        mc+=tf*dis[t];
    }
    return P(mc,mf);
}
int a[MAXN],b[MAXN],p[MAXN];
char str[MAXN],ss[MAXN];
struct NODE{
    int lo,hi;
    NODE(int ll,int hh){
        lo=ll;
        hi=hh;
    }
    bool operator < (const NODE &r) const{
        if(lo!=r.lo) return lo<r.lo;
        return hi<r.hi;
    }
};
vector<NODE> vec[MAXN];
int main(){
    int len;
    while(cin>>len){
        scanf("%s",str+1);

        int v=read();
        int cnt=0;
        rep(i,1,v){
            scanf("%s",ss+1); p[i]=read();
            int len2=strlen(ss+1);
            rep(j,1,len-len2+1){
                bool flag=1;
                rep(jj,1,len2){
                    if(ss[jj]!=str[j+jj-1]){
                        flag=0;
                        break;
                    }
                }
                if(flag) vec[i].push_back(NODE(j,j+len2-1)),b[++cnt]=j,b[++cnt]=j+len2-1;
            }
        }
        int k=read();
        sort(b+1,b+1+cnt);
        cnt=unique(b+1,b+1+cnt)-b-1;
        rep(i,1,v){
            for(int j=0;j<vec[i].size();j++){
                vec[i][j].lo=lower_bound(b+1,b+1+cnt,vec[i][j].lo)-b;
                vec[i][j].hi=lower_bound(b+1,b+1+cnt,vec[i][j].hi)-b;
                // cout<<vec[i][j].lo<<" "<<vec[i][j].hi<<endl;
            }
        }
        int tt=cnt+1;s=1;t=tt+1;n=t;
        init();
        rep(i,1,tt) add(i,i+1,k,0);
        rep(i,1,v){
            for(int j=0;j<vec[i].size();j++){
                add(vec[i][j].lo,vec[i][j].hi+1,1,-p[i]);
            }
        }
        P ans=mcmf();
        println(-ans.first);
    }
    return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

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

const int N = 1e6 + 5;

/***************************************************************************/

const int INF = 1e9 + 7;

struct rib {
	int b, u, c, f;
	size_t back;
};

void add_rib (vector < vector<rib> > & g, int a, int b, int u, int c) {
	rib r1 = { b, u, c, 0, g[b].size() };
	rib r2 = { a, 0, -c, 0, g[a].size() };
	g[a].push_back (r1);
	g[b].push_back (r2);
}

pair<int, int> minCostFlow(int n, int k, int s, int t, vector < vector<rib> > & g) {

    int flow = 0,  cost = 0;
	while (flow < k) {
		vector<int> id (n, 0);
		vector<int> d (n, INF);
		vector<int> q (n);
		vector<int> p (n);
		vector<size_t> p_rib (n);
		int qh=0, qt=0;
		q[qt++] = s;
		d[s] = 0;
		while (qh != qt) {
			int v = q[qh++];
			id[v] = 2;
			if (qh == n)  qh = 0;
			for (size_t i=0; i<g[v].size(); ++i) {
				rib & r = g[v][i];
				if (r.f < r.u && d[v] + r.c < d[r.b]) {
					d[r.b] = d[v] + r.c;
					if (id[r.b] == 0) {
						q[qt++] = r.b;
						if (qt == n)  qt = 0;
					}
					else if (id[r.b] == 2) {
						if (--qh == -1)  qh = n-1;
						q[qh] = r.b;
					}
					id[r.b] = 1;
					p[r.b] = v;
					p_rib[r.b] = i;
				}
			}
		}
		if (d[t] == INF)  break;
		int addflow = k - flow;
		for (int v=t; v!=s; v=p[v]) {
			int pv = p[v];  size_t pr = p_rib[v];
			addflow = min (addflow, g[pv][pr].u - g[pv][pr].f);
		}
		for (int v=t; v!=s; v=p[v]) {
			int pv = p[v];  size_t pr = p_rib[v],  r = g[pv][pr].back;
			g[pv][pr].f += addflow;
			g[v][r].f -= addflow;
			cost += g[pv][pr].c * addflow;
		}
		flow += addflow;
	}

	return make_pair(flow, cost);
}

int lps[N];

void computeLPS(string &pat) {

    int m = pat.length();

    int len = 0;
    lps[0] = 0;

    int i = 1;
    while(i < m) {

        if(pat[i] == pat[len]) {
            len++;
            lps[i] = len;
            i++;
        }
        else {
            if(len) len = lps[len-1];
            else lps[i++] = 0;
        }
    }
}

vector<int> ans;

void Find(string &str, string &pat) {

    int n = str.length();
    int m = pat.length();

    int i, j;
    i = j = 0;

    while(i < n) {

        if(str[i] == pat[j]) {
            i++, j++;
            if(j == m) {
                ans.push_back(i-j+1);
                j = lps[j-1];
            }
        }
        else {
            if(j) j = lps[j-1];
            else i++;
        }
    }
}

int main() {

	boost;
	int n; cin>>n; vector < vector<rib> > g (n+2);
	for(int i=1; i<=n+1; i++) {
		add_rib(g, i-1, i, INF, 100);
	}
	string s; cin>>s;
	int m; cin>>m;
	for(int i=1; i<=m; i++) {
		string t; int p;
		cin>>t>>p;
		computeLPS(t);
		ans.clear();
		Find(s, t);
		for(int j : ans) {
			int k = j + t.length();
			add_rib(g, j, k, 1, (k-j)*100 - p);
		}
	}
	int x; cin>>x;
	auto ret = minCostFlow(n+2, x, 0, n+1, g);
	int ans = (n+1)*100*x - ret.se;
	cout<<ans<<"\n";
	return 0;
}


#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);
					}
				}
			}
		}

        if (dist[t] == INF) break;

		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;

#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 = 100; // maximum number of cubes

struct Edge
{
    int from, to, capacity, cost;
};

vector<vector<int>> adj, cost, capacity;

const int INF = 1e9;

void shortest_paths(int n, int v0, vector<int>& d, vector<int>& p) {
    d.assign(n, INF);
    d[v0] = 0;
    vector<int> m(n, 2);
    deque<int> q;
    q.push_back(v0);
    p.assign(n, -1);

    while (!q.empty()) {
        int u = q.front();
        q.pop_front();
        m[u] = 0;
        for (int v : adj[u]) {
            if (capacity[u][v] > 0 && d[v] > d[u] + cost[u][v]) {
                d[v] = d[u] + cost[u][v];
                p[v] = u;
                if (m[v] == 2) {
                    m[v] = 1;
                    q.push_back(v);
                } else if (m[v] == 0) {
                    m[v] = 1;
                    q.push_front(v);
                }
            }
        }
    }
}

int min_cost_flow(int N, vector<Edge> edges, int K, int s, int t) {
    adj.assign(N, vector<int>());
    cost.assign(N, vector<int>(N, 0));
    capacity.assign(N, vector<int>(N, 0));
    for (Edge e : edges) {
        adj[e.from].push_back(e.to);
        adj[e.to].push_back(e.from);
        cost[e.from][e.to] = e.cost;
        cost[e.to][e.from] = -e.cost;
        capacity[e.from][e.to] = e.capacity;
    }

    int flow = 0;
    int cost = 0;
    vector<int> d, p;
    while (flow < K) {
        shortest_paths(N, s, d, p);
        if (d[t] == INF)
            break;

        // find max flow on that path
        int f = K - flow;
        int cur = t;
        while (cur != s) {
            f = min(f, capacity[p[cur]][cur]);
            cur = p[cur];
        }

        // apply flow
        flow += f;
        cost += f * d[t];
        cur = t;
        while (cur != s) {
            capacity[p[cur]][cur] -= f;
            capacity[cur][p[cur]] += f;
            cur = p[cur];
        }
    }

    if (flow < K)
        return -1;
    else
        return cost;
}

int main()
{
    vector<Edge> edges;
    int n;
    I(n);
    string s;
    I(s);
    int N = n + 2;
    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) {
                Edge e;
                e.from = i; e.to = i + SZ(s1); e.capacity = 1; e.cost = -x;
                edges.pb(e);
            }
        }
    }
    int x;
    I(x);
    for (int i = 0; i < n; i++) {
        Edge e;
        if (i == 0) {
            e.from = N - 1; e.to = i; e.capacity = x; e.cost = 0;
        }
        else {
            e.from = i - 1; e.to = i; e.capacity = INF; e.cost = 0;
        }
        edges.pb(e);
        e.from = i; e.to = i + 1; e.capacity = INF; e.cost = 0;
        edges.pb(e);
    }
    int ans = min_cost_flow(N, edges, x, N - 1, N - 2);
    O(-ans);

    return 0;
}


#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 cost = 0, flow = 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);
					}
				}
			}
		}

        if (dist[t] == INF) break;
		int d = f;

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

		f -= d;
		flow += d;
		cost += 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 cost;
}

/*... 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, x);
    O(ans);

    return 0;
}


#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, x);
    O(ans);

    return 0;
}