Problem: This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

Output the final string after applying the queries.

Input

The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively. 

Next line contains a string S itself. It contains only lowercase English letters.

Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, <image>).

Output

Output one line, the string S after applying the queries.

Examples

Input

10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1


Output

cbcaaaabdd

Input

10 1
agjucbvdfk
1 10 1


Output

abcdfgjkuv

Note

First sample test explanation:

<image>

<image>

<image>

<image>

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
string s;
int f[26];
int cnt[26][400005];
int lazy[26][400005];
void build(int pos, int low, int high) {
  int i;
  if (low == high) {
    for (i = 0; i < 26; i++) {
      lazy[i][pos] = -1;
      cnt[i][pos] = 0;
    }
    cnt[s[low] - 'a'][pos] = 1;
    return;
  }
  int lc = 2 * pos + 1, rc = lc + 1, mid = (low + high) / 2;
  build(lc, low, mid);
  build(rc, mid + 1, high);
  for (i = 0; i < 26; i++) {
    lazy[i][pos] = -1;
    cnt[i][pos] = cnt[i][lc] + cnt[i][rc];
  }
}
void update(int treeno, int pos, int low, int high, int l, int r, int v) {
  if (l > r) return;
  int lc = 2 * pos + 1, rc = lc + 1, mid = (low + high) / 2;
  if (lazy[treeno][pos] != -1) {
    cnt[treeno][pos] = lazy[treeno][pos] * (high - low + 1);
    if (low != high) {
      lazy[treeno][lc] = lazy[treeno][pos];
      lazy[treeno][rc] = lazy[treeno][pos];
    }
    lazy[treeno][pos] = -1;
  }
  if (low == l && high == r) {
    cnt[treeno][pos] = v * (high - low + 1);
    if (low != high) {
      lazy[treeno][lc] = v;
      lazy[treeno][rc] = v;
    }
    return;
  }
  if (r <= mid)
    update(treeno, lc, low, mid, l, r, v);
  else if (l > mid)
    update(treeno, rc, mid + 1, high, l, r, v);
  else {
    update(treeno, lc, low, mid, l, mid, v);
    update(treeno, rc, mid + 1, high, mid + 1, r, v);
  }
  if (lazy[treeno][lc] == -1)
    cnt[treeno][pos] = cnt[treeno][lc];
  else
    cnt[treeno][pos] = lazy[treeno][lc] * (mid - low + 1);
  if (lazy[treeno][rc] == -1)
    cnt[treeno][pos] += cnt[treeno][rc];
  else
    cnt[treeno][pos] =
        cnt[treeno][pos] + lazy[treeno][rc] * (high - mid - 1 + 1);
}
int query(int treeno, int pos, int low, int high, int l, int r) {
  if (l > r) return 0;
  int lc = 2 * pos + 1, rc = lc + 1, mid = (low + high) / 2;
  if (lazy[treeno][pos] != -1) {
    cnt[treeno][pos] = lazy[treeno][pos] * (high - low + 1);
    if (low != high) {
      lazy[treeno][lc] = lazy[treeno][pos];
      lazy[treeno][rc] = lazy[treeno][pos];
    }
    lazy[treeno][pos] = -1;
  }
  if (low == l && high == r) return cnt[treeno][pos];
  if (r <= mid) return query(treeno, lc, low, mid, l, r);
  if (l > mid) return query(treeno, rc, mid + 1, high, l, r);
  return query(treeno, lc, low, mid, l, mid) +
         query(treeno, rc, mid + 1, high, mid + 1, r);
}
void make(int treeno, int pos, int low, int high) {
  int lc = 2 * pos + 1, rc = lc + 1, mid = (low + high) / 2;
  if (lazy[treeno][pos] != -1) {
    cnt[treeno][pos] = lazy[treeno][pos] * (high - low + 1);
    if (low != high) {
      lazy[treeno][lc] = lazy[treeno][pos];
      lazy[treeno][rc] = lazy[treeno][pos];
    }
    lazy[treeno][pos] = -1;
  }
  if (cnt[treeno][pos] == 0) return;
  if (low == high) {
    s[low] = 'a' + treeno;
    return;
  }
  make(treeno, lc, low, mid);
  make(treeno, rc, mid + 1, high);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, q, i, l, r, op, cidx;
  cin >> n >> q;
  cin >> s;
  build(0, 0, n - 1);
  while (q--) {
    cin >> l >> r >> op;
    l--;
    r--;
    for (i = 0; i < 26; i++) f[i] = query(i, 0, 0, n - 1, l, r);
    if (op) {
      for (i = 0; i < 26; i++) update(i, 0, 0, n - 1, l, r, 0);
      cidx = l;
      for (i = 0; i < 26; i++) {
        update(i, 0, 0, n - 1, cidx, cidx + f[i] - 1, 1);
        cidx = cidx + f[i];
      }
    } else {
      for (i = 0; i < 26; i++) update(i, 0, 0, n - 1, l, r, 0);
      cidx = r;
      for (i = 0; i < 26; i++) {
        update(i, 0, 0, n - 1, cidx - f[i] + 1, cidx, 1);
        cidx = cidx - f[i];
      }
    }
  }
  for (i = 0; i < 26; i++) make(i, 0, 0, n - 1);
  cout << s << "\n";
  return 0;
}