#include <iostream>
#include <map>
#include <set>
#include <deque>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <iterator>
#include <ctime>
#include <cmath>
#include <fstream>
#include <stdio.h>
#include <assert.h>
#include <bitset>

using namespace std;

struct vertex {
	int cost;
	bool f;
	vector<int> next;
} t[15 * 1000 * 1000 + 1];

const int MAXN = 5000;
int sz, calc[MAXN + 1][MAXN + 1];
long long dp[MAXN + 1];

void add(string& s, int cost) {
	int v = 0;
	for (int i = 0; i < (int)s.size(); i++) {
		int c = s[i] - '0';
		if (t[v].next[c] == -1) {
			t[v].next[c] = ++sz;
			t[sz].cost = 1e9;
			t[sz].next.assign(2, -1);
		}
		v = t[v].next[c];
	}
	t[v].cost = min(t[v].cost, cost);
	t[v].f = true;
}

int main() {
	ios_base::sync_with_stdio(false);
	ifstream cin("typing.in");
	ofstream cout("typing.out");

	int m, n, l;
	cin >> m >> n >> l;
	assert(m <= 5000 && l <= 5000);
	string s;
	cin >> s;
	t[0].next.assign(2, -1);
	for (int i = 0; i <= MAXN; i++)
		for (int j = 0; j <= MAXN; j++)
			calc[i][j] = 1e9;
	for (int i = 0; i < n; i++) {
		int cost;
		cin >> cost;
		string s;
		cin >> s;
		add(s, cost);
		string temp = "";
		for (int j = 1; j <= (int)s.size(); j++) {
			temp += s[j - 1];
			add(temp, cost);
		}
		temp = "";
		for (int j = (int)s.size(); j >= 1; j--) {
			temp = s[j - 1] + temp;
			add(temp, cost);
		}
	}
	for (int i = 1; i <= m; i++) {
		int v = 0;
		for (int j = i; j <= m; j++) {
			v = t[v].next[s[j - 1] - '0'];
			if (v == -1)
				break;
			if(t[v].f)
				calc[i][j] = t[v].cost;
		}
	}
	for (int i = 1; i <= m; i++)
		dp[i] = 1e18;
	for (int i = 1; i <= m; i++) {
		int v = 0;
		for (int j = i; j >= 1 && i - j + 1 <= 1000; j--) {
			if(calc[j][i] < 1e9)
				dp[i] = min(dp[i], dp[j - 1] + calc[j][i]);
		}
	}
	if (dp[m] < 1e18)
		cout << dp[m] << endl;
	else
		cout << -1 << endl;
	return 0;
}