/*
用 log去掉次方然后变成裸的01分数规划问题
具体来说是要给每个trans赋值, 然后跑取max转移吧
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<cmath>
#define ll long long
#define M 1520
#define mmp make_pair
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
char s[M], tmp[M];
double f[M][M];
int n, m, pre[M][M], note[M], as[M][M];
struct AC {
#define ch son
int fail[M], son[M][10], end[M], cnt, fa[M], biao[M];
double sum[M], trans[M], v[M], cost[M];
void insert(double x) {
int now = 0, len = strlen(tmp + 1);
for(int i = 1; i <= len; i++) {
if(ch[now][tmp[i] - '0'] == 0) ch[now][tmp[i] - '0'] = ++cnt, fa[cnt] = now, biao[cnt] = tmp[i] - '0';
now = ch[now][tmp[i] - '0'];
}
v[now] += x, end[now]++;
}
void getfail() {
queue<int> q;
for(int i = 0; i < 10; i++) if(son[0][i] != 0) fail[son[0][i]] = 0, q.push(son[0][i]), trans[son[0][i]] = v[son[0][i]], sum[son[0][i]] = end[son[0][i]];
while(!q.empty()) {
int now = q.front();
q.pop();
for(int i = 0; i < 10; i++) {
if(son[now][i] != 0) {
fail[son[now][i]] = son[fail[now]][i];
trans[son[now][i]] += trans[son[fail[now]][i]];
sum[son[now][i]] += sum[son[fail[now]][i]];
if(end[son[now][i]]) trans[son[now][i]] += v[son[now][i]], sum[son[now][i]] += end[son[now][i]];
q.push(son[now][i]);
} else son[now][i] = son[fail[now]][i];
}
}
// for(int i = 0; i < 10; i++) if(ch[0][i] == 0) biao[0] = i;
}
} ac;
const double inf = pow(2, 70);
void cl() {
for(int i = 0; i <= n; i++) for(int j = 0; j <= ac.cnt; j++) f[i][j] = -inf;//, pre[i][j] = 0, as[i][j] = 0;
}
void dp() {
f[0][0] = 0;
for(int i = 1; i <= n; i++) {
if(s[i] == '.') {
for(int j = 0; j <= ac.cnt; j++) {
for(int k = 0; k < 10; k++) {
if(f[i][ac.son[j][k]] < f[i - 1][j] + ac.cost[ac.son[j][k]])
f[i][ac.son[j][k]] = f[i - 1][j] + ac.cost[ac.son[j][k]],
pre[i][ac.son[j][k]] = j,
as[i][ac.son[j][k]] = k;
}
}
} else {
int k = s[i] - '0';
for(int j = 0; j <= ac.cnt; j++) {
if(f[i][ac.son[j][k]] < f[i - 1][j] + ac.cost[ac.son[j][k]])
f[i][ac.son[j][k]] = f[i - 1][j] + ac.cost[ac.son[j][k]],
pre[i][ac.son[j][k]] = j,
as[i][ac.son[j][k]] = k;
}
}
}
}
bool check(double x) {
for(int i = 1; i <= ac.cnt; i++) ac.cost[i] = ac.trans[i] - x * ac.sum[i];
cl();
dp();
for(int i = 0; i <= ac.cnt; i++) {
if(f[n][i] > 0) {
int now = i;
for(int j = n; j >= 1; j--) {
note[j] = as[j][now];
now = pre[j][now];
}
return true;
}
}
return false;
}
void getans() {
double l = 0, r = 1.0 * 1e8;
int up;
if(n <= 501) up = 120;
else up = 42;
for(int j = 1; j <= up; j++) {
double mid = (l + r) / 2;
if(check(mid)) l = mid;
else r = mid;
}
// printf("%.10lf\n", exp(l));
}
int main() {
n = read(), m = read();
scanf("%s", s + 1);
for(int i = 1; i <= m; i++) {
scanf("%s", tmp + 1);
double v = read();
v = log(v);
ac.insert(v);
}
for(int i = 1; i <= n; i++) note[i] = s[i] - '0';
ac.getfail();
getans();
for(int i = 1; i <= n; i++) cout << note[i];
cout << "\n";
return 0;
}