#include <iostream>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <iterator>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <time.h>
#pragma warning(disable: 4996)
typedef long long ll;
typedef long double ld;
using namespace std;

const ll SZ = 5e5;
const ll INF = 1e15;

ll d[SZ], c;
ll a[SZ], k[SZ][200], cc[SZ];
string st, x, b;
ll segTree[SZ], segTreePush[SZ];
bool p[SZ];

struct vertex {
	ll cost;
	vertex *l, *r;
	vertex() {
		l = r = NULL;
		cost = INF;
	}
};
vertex *t = new vertex(), *f = new vertex();

void add(vertex *t, ll p) {
	t->cost = min(t->cost, c);
	if (p == x.size())
		return;
	if (x[p] == '0') {
		if (!t->l)
			t->l = new vertex();
		add(t->l, p + 1);
	} else {
		if (!t->r)
			t->r = new vertex();
		add(t->r, p + 1);
	}
}

void preupd(vertex *t, ll p, ll addto) {
	d[addto] = min(d[addto], d[p] + t->cost);
	if (!p)
		return;
	if (st[p - 1] == '0' && t->l)
		preupd(t->l, p - 1, addto);
	if (st[p - 1] == '1' && t->r)
		preupd(t->r, p - 1, addto);
}

void update(vertex *t, ll p, ll add) {
	d[p] = min(d[p], add + t->cost);
	if (p == st.length())
		return;
	if (st[p] == '0' && t->l)
		update(t->l, p + 1, add);
	if (st[p] == '1' && t->r)
		update(t->r, p + 1, add);
}

void prefixFunc() {
	a[0] = 0;
	for (ll i = 1; i < x.length(); i++) {
		ll t = a[i - 1];
		while (t && x[i] != x[t])
			t = a[t - 1];
		if (!t)
			a[i] = ll(x[0] == x[i]);
		else
			a[i] = t + 1;
	}
}

void zFunc() {
	a[0] = x.length();
	ll l = 0, r = 0;
	for (ll i = 1; i < x.length(); i++) {
		if (r < i)
			a[i] = 0;
		else
			a[i] = min(r - i + 1, a[i - l]);
		while (i + a[i] < x.length() && x[a[i]] == x[i + a[i]])
			a[i]++;
		if (i + a[i] - 1 > r)
			l = i, r = i + a[i] - 1;
	}
}

void push(ll h, ll a, ll b) {
	if (!p[h])
		return;
	p[h] = false;
	segTree[h] = min(segTree[h], segTreePush[h]);
	if (a != b - 1) {
		if (p[2 * h + 1])
			segTreePush[2 * h + 1] = min(segTreePush[2 * h + 1], segTreePush[h]);
		else
			segTreePush[2 * h + 1] = segTreePush[h];
		if (p[2 * h + 2])
			segTreePush[2 * h + 2] = min(segTreePush[2 * h + 2], segTreePush[h]);
		else
			segTreePush[2 * h + 2] = segTreePush[h];
		p[2 * h + 1] = p[2 * h + 2] = true;
	}
}

void upd(ll h, ll a, ll b, ll l, ll r, ll mean) {
	push(h, a, b);
	if (a >= l && b <= r) {
		segTreePush[h] = mean;
		p[h] = true;
		push(h, a, b);
		return;
	}
	if (b <= l || r <= a)
		return;
	ll m = (a + b) >> 1;
	upd(2 * h + 1, a, m, l, r, mean);
	upd(2 * h + 2, m, b, l, r, mean);
}

ll get(ll h, ll a, ll b, ll x) {
	push(h, a, b);
	if (a == b - 1)
		return segTree[h];
	ll m = (a + b) >> 1;
	if (x < m)
		return get(2 * h + 1, a, m, x);
	else
		return get(2 * h + 2, m, b, x);
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	freopen("typing.in", "r", stdin);
	freopen("typing.out", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	srand(654536633);

	ll n, m, l;
	cin >> n >> m >> l >> st;

	if (m <= 200) {
		for (ll i = 0; i < m; i++) {
			cin >> cc[i] >> b;
			x = b + '#' + st;
			zFunc();
			for (ll j = b.length() + 1; j < x.length(); j++)
				k[j - b.length() - 1][i] = max(k[j - b.length() - 1][i], a[j]);
			reverse(st.begin(), st.end());
			reverse(b.begin(), b.end());
			x = b + '#' + st;
			prefixFunc();
			for (ll j = b.length() + 1; j < x.length(); j++)
				k[n - 1 - (j - b.length() - 1)][i] = max(k[n - 1 - (j - b.length() - 1)][i], a[j]);
			reverse(st.begin(), st.end());
		}

		for (ll i = 0; i < 5 * n; i++)
			segTree[i] = INF;
		upd(0, 0, n + 1, 0, 1, 0);

		for (ll i = 0; i < n; i++) {
			ll xx = get(0, 0, n + 1, i);
			for (ll j = 0; j < m; j++)
				upd(0, 0, n + 1, i, i + k[i][j] + 1, xx + cc[j]);
		}

		ll xx = get(0, 0, n + 1, n);
		cout << (xx == INF ? -1 : xx);

		return 0;
	}

	for (ll i = 0; i < m; i++) {
		cin >> c >> x;
		add(t, 0);
		reverse(x.begin(), x.end());
		add(f, 0);
	}

	for (ll i = 1; i <= n; i++)
		d[i] = INF;
	for (ll i = 0; i < n; i++) {
		preupd(f, i, i);
		update(t, i, d[i]);
	}
	preupd(f, n, n);

	cout << (d[n] == INF ? -1 : d[n]);
	
	return 0;
}