#include <bits/stdc++.h>
using namespace std;
const int N = 200002;
int get(char c) {
  if (c >= 'a' && c <= 'z') return c - 'a';
  if (c >= 'A' && c <= 'Z') return c - 'A' + 26;
  return c - '0' + 52;
}
struct node {
  vector<int> v;
  int cnt;
  node() {
    v = vector<int>(62, 0);
    cnt = 0;
  }
};
node tree[3 * N];
char s[N], ans[N];
void build(int pos, int l, int r) {
  if (l == r) {
    tree[pos].v[get(s[l])]++;
    tree[pos].cnt++;
    return;
  }
  int mid = (l + r) / 2;
  build(pos * 2, l, mid);
  build(pos * 2 + 1, mid + 1, r);
  for (int i = 0; i < 62; i++)
    tree[pos].v[i] = tree[pos * 2].v[i] + tree[pos * 2 + 1].v[i];
  tree[pos].cnt = tree[pos * 2].cnt + tree[pos * 2 + 1].cnt;
}
int remove(int pos, int l, int r, int qLow, int qHigh, int c, int currLeft,
           int currRight) {
  if (l > r || currLeft > currRight || !tree[pos].v[c] || qLow > currRight ||
      qHigh < currLeft)
    return 0;
  if (l == r) {
    tree[pos].v[c] = 0;
    tree[pos].cnt = 0;
    ans[l] = 0;
    return 1;
  }
  int mid = (l + r) / 2;
  int cntLeft = tree[pos * 2].cnt;
  int ret =
      remove(pos * 2, l, mid, qLow, qHigh, c, currLeft, currLeft + cntLeft - 1);
  ret += remove(pos * 2 + 1, mid + 1, r, qLow, qHigh, c, currLeft + cntLeft,
                currRight);
  tree[pos].cnt -= ret;
  tree[pos].v[c] -= ret;
  return ret;
}
int main() {
  int n, m;
  scanf("%d %d\n", &n, &m);
  scanf("%s", s + 1);
  strcpy(ans, s);
  for (int i = 1; i <= n; i++) ans[i] = s[i];
  build(1, 1, n);
  int cnt = n;
  for (int i = 0; i < m; i++) {
    int l, r;
    char c;
    scanf("%d %d %c", &l, &r, &c);
    remove(1, 1, n, l, r, get(c), 1, cnt);
  }
  for (int i = 1; i <= n; i++)
    if (ans[i]) printf("%c", ans[i]);
  return 0;
}
