#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <bitset>
#include <algorithm>
#include <cassert>
#include <ctime>

using namespace std;

struct node {
	long long cost;
	vector<int> moves;
	node() { cost = 999999999, moves = vector<int>(2, -1); }
};

vector<node> bor;

void add_str(string s, long long cost) {
	int ind = 0;
	for (int i = 0; i < s.size(); i++) {
		if (bor[ind].moves[s[i] - '0'] == -1)
			bor[ind].moves[s[i] - '0'] = bor.size(), bor.push_back(node());
		ind = bor[ind].moves[s[i] - '0'];
		bor[ind].cost = min(cost, bor[ind].cost);
	}
}

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	freopen("typing.in", "r", stdin);
	freopen("typing.out", "w", stdout);
	int n, m, l;
	string s;
	cin >> m >> n >> l;
	cin >> s;
	bor.push_back(node());
	for (int i = 0; i < n; i++) {
		int cst;
		string cs;
		cin >> cst >> cs;
		add_str(cs, cst);
		reverse(cs.begin(), cs.end());
		add_str(cs, cst);
	}
	vector<long long> dp(s.size() + 1, 1000LL * 1000 * 1000 * 1000 * 1000);
	dp[0] = 0;
	for (int i = 0; i < s.size(); i++) {
		int ind = 0, j = 0;
		while (i + j < s.size() && bor[ind].moves[s[i + j] - '0'] != -1) {
			ind = bor[ind].moves[s[i + j] - '0'], dp[i + j + 1] = min(dp[i + j + 1], dp[i] + bor[ind].cost), j++;
		}
	}
	if (dp[s.size()] == 1000LL * 1000 * 1000 * 1000 * 1000)
		cout << -1 << endl;
	else
		cout << dp[s.size()] << endl;
	return 0;
}

