#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <unordered_map>

using namespace std;

#define int long long
unordered_map <string, int> mmm;
const long long INF = 1234567890123456789;
int m, n, L;
string hh;
int mod = 1e9 + 7;
int p = 228;
int ppow[1000000];
int t[1000000];
int md[1000000];
int get_otr(vector <int> &v, int l, int r) {
	return (v[r] - (l ? (v[l - 1] * ppow[r - l + 1]) : 0) + mod * mod) % mod;
}
vector <int> get_h(string s) {
	vector <int> v(s.size());
	for (int i = 0; i < s.size(); ++i) {
		v[i] = (i ? v[i - 1] : 0) * p + s[i] - '0' + 1;
		v[i] %= mod;
	}
	return v;
}
void push(int v, int tl, int tr) {
	if (md[v] == 0) return;
	if (tl != tr) {
		if (md[v * 2]) {
			md[v * 2] = min(md[v * 2], md[v]);
		}
		if (md[v * 2 + 1]) {
			md[v * 2 + 1] = min(md[v * 2 + 1], md[v]);
		}
	}
	t[v] = min(t[v], md[v]);
	md[v] = 0;
}
void built(int v, int tl, int tr, vector <int> &arr) {
	if (tl == tr) {
		t[v] = arr[tl];
		return;
	}
	int tm = (tl + tr) / 2;
	built(v * 2, tl, tm, arr);
	built(v * 2 + 1, tm + 1, tr, arr);
	t[v] = min(t[v * 2], t[v * 2 + 1]);
}
int get_min(int v, int tl, int tr, int l, int r) {
	if (l > tr || tl > r) {
		return INF;
	}
	push(v, tl, tr);
	if (tl >= l && tr <= r) {
		return t[v];
	}
	int tm = (tl + tr) / 2;
	return min(get_min(v * 2, tl, tm, l, r), get_min(v * 2 + 1, tm + 1, tr, l, r));
}

void donah(int v, int tl, int tr, int l, int r, int x) {
	if (l > tr || tl > r) {
		return;
	}
	if (tl >= l && tr <= r) {
		md[v] = x;
		push(v, tl, tr);
		return;
	}
	push(v, tl, tr);
	int tm = (tl + tr) / 2;
	donah(v * 2, tl, tm, l, r, x);
	donah(v * 2 + 1, tm + 1, tr, l, r, x);
	t[v] = min(t[v * 2], t[v * 2 + 1]);
}
void res() {
	ppow[0] = 1;
	for (int i = 1; i < 1e6; ++i) {
		ppow[i] = ppow[i - 1] * p;
		ppow[i] %= mod;
	}
	vector <pair <string, int> > v;
	for (int i = 0; i < n; ++i) {
		int k;
		cin >> k;
		string s;
		cin >> s;
		v.push_back(make_pair(s, k));
	}
	vector <vector <int> > vh;
	for (auto it : v) {
		vh.push_back(get_h(it.first));
	}
	vector <int> nase = get_h(hh);
	vector <int> dp(hh.size(), INF);
	built(1, 0, hh.size() - 1, dp);
	for (int i = 0; i < hh.size(); ++i) {
		for (int j = 0; j < n; ++j) {
			int bot = 0;
			int top = min(i + 1, (int)v[j].first.size()) + 1;
			while (top > bot + 1) {
				int mid = (bot + top) / 2;
				if (get_otr(vh[j], v[j].first.size() - mid, v[j].first.size() - 1) == get_otr(nase, i - mid + 1, i)) {
					bot = mid;
				}
				else {
					top = mid;
				}
			}
			int minn;
			if (i - bot < 0) {
				minn = 0;
			}
			else {
				minn = get_min(1, 0, dp.size() - 1, i - bot, i - 1);
			}
			donah(1, 0, dp.size() - 1, i, i, minn + v[j].second);
			bot = 0;
			top = min((int)hh.size() - i, (int)v[j].first.size()) + 1;
			while (top > bot + 1) {
				int mid = (bot + top) / 2;
				if (get_otr(vh[j], 0, mid - 1) == get_otr(nase, i, i + mid - 1)) {
					bot = mid;
				}
				else {
					top = mid;
				}
			}
			int curr = i ? get_min(1, 0, dp.size() - 1, i - 1, i - 1) : 0;
			donah(1, 0, dp.size() - 1, i, i + bot - 1, curr + v[j].second);
		}
	}
	cout << (get_min(1, 0, dp.size() - 1, dp.size() - 1, dp.size() - 1) == INF ? -1 : get_min(1, 0, dp.size() - 1, dp.size() - 1, dp.size() - 1)) << endl;
	exit(0);
}
signed main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	freopen("typing.in", "r", stdin);
	freopen("typing.out", "w", stdout);

	cin >> m >> n >> L;
	cin >> hh;
	if (L > 5000) {
		res();
	}
	for (int i = 1; i <= n; ++i) {
		int k;
		string s;
		cin >> k >> s;
		for (int i = 0; i < s.size(); ++i) {
			if (mmm.count(s.substr(0, i + 1))) {
				mmm[s.substr(0, i + 1)] = min(mmm[s.substr(0, i + 1)], k);
			}
			else {
				mmm[s.substr(0, i + 1)] = k;
			}
		}
		for (int i = s.size() - 1; i > 0; --i) {
			if (mmm.count(s.substr(i, s.size() - i))) {
				mmm[s.substr(i, s.size() - i)] = min(mmm[s.substr(i, s.size() - i)], k);
			}
			else {
				mmm[s.substr(i, s.size() - i)] = k;
			}
		}
	}
	hh = 'a' + hh;
	vector <long long> dp(hh.size(), INF);
	dp[0] = 0;
	for (int i = 1; i <= m; ++i) {
		for (int j = max(1LL, i - 1000); j <= i; ++j) {
			if (mmm.count(hh.substr(j, i - j + 1))) {
				dp[i] = min(dp[i], dp[j - 1] + mmm[hh.substr(j, i - j + 1)]);
			}
		}
	}
	cout << (dp[m] == INF ? -1 : dp[m]) << endl;
}