#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
struct Node {
  int l, r, sum;
} tree[maxn * 4];
int pos[maxn];
void build(int x, int l, int r) {
  tree[x].l = l;
  tree[x].r = r;
  tree[x].sum = r - l + 1;
  if (l == r) {
    pos[l] = x;
    return;
  }
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
}
int find(int x, int targ) {
  if (tree[x].l == tree[x].r) return tree[x].l;
  if (targ <= tree[x << 1].sum) return find(x << 1, targ);
  return find(x << 1 | 1, targ - tree[x << 1].sum);
}
inline void modify(int p, int dt) {
  int f = pos[p];
  while (f) {
    tree[f].sum += dt;
    f = f >> 1;
  }
}
int n, m;
char s[maxn];
set<int> st[62];
inline int getcode(char c) {
  if (c >= 'a' && c <= 'z') return c - 'a';
  if (c >= 'A' && c <= 'Z') return c - 'A' + 26;
  return c - '0' + 52;
}
int lst[maxn], cnt = 0;
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m >> (s + 1);
  build(1, 1, n);
  for (int i = 1; i <= n; i++) st[getcode(s[i])].insert(i);
  for (int i = 1; i <= m; i++) {
    int l, r;
    char c;
    int cd;
    cin >> l >> r >> c;
    cd = getcode(c);
    cnt = 0;
    int x = find(1, l);
    int y = find(1, r);
    set<int>::iterator it = lower_bound(st[cd].begin(), st[cd].end(), x);
    while (true) {
      if (it == st[cd].end()) break;
      if (*it > y) break;
      lst[++cnt] = *it;
      set<int>::iterator itt = it;
      it++;
      st[cd].erase(itt);
    }
    for (int j = 1; j <= cnt; j++) modify(lst[j], -1);
  }
  for (int i = 1; i <= n; i++) {
    if (tree[pos[i]].sum) cout << s[i];
  }
  cout << endl;
  return 0;
}
