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;
const int M = 1e5 + 7;
int tree[27][3 * M], lazy[27][3 * M], curcnt[30];
string s;
int merg(int l, int r) { return l + r; }
void relax(int id, int node, int beg, int ed) {
  tree[id][node] = (ed - beg + 1) * lazy[id][node];
  if (beg == ed) return;
  lazy[id][2 * node] = lazy[id][2 * node + 1] = lazy[id][node];
  lazy[id][node] = -1;
}
void update(int id, int node, int beg, int ed, int l, int r, int k) {
  if (lazy[id][node] != -1) relax(id, node, beg, ed);
  if (beg > r || ed < l) return;
  if (beg >= l && ed <= r) {
    lazy[id][node] = k;
    relax(id, node, beg, ed);
    return;
  }
  int mid = (beg + ed) >> 1;
  int lft = 2 * node;
  int rgt = lft + 1;
  update(id, lft, beg, mid, l, r, k);
  update(id, rgt, mid + 1, ed, l, r, k);
  tree[id][node] = merg(tree[id][lft], tree[id][rgt]);
}
int query(int id, int node, int beg, int ed, int l, int r) {
  if (lazy[id][node] != -1) relax(id, node, beg, ed);
  if (beg > r || ed < l) return 0;
  if (beg >= l && ed <= r) return tree[id][node];
  int mid = (beg + ed) >> 1;
  int lft = 2 * node;
  int rgt = lft + 1;
  int p = query(id, lft, beg, mid, l, r);
  int q = query(id, rgt, mid + 1, ed, l, r);
  return merg(p, q);
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);
  memset(lazy, -1, sizeof lazy);
  int n, q;
  cin >> n >> q;
  cin >> s;
  int sz = s.size();
  for (int i = 0; i < sz; i++) {
    int id = s[i] - 'a';
    update(id, 1, 1, n, i + 1, i + 1, 1);
  }
  string res = "";
  while (q--) {
    int x, y, z;
    cin >> x >> y >> z;
    for (int i = 0; i < 26; i++) {
      curcnt[i] = 0;
      curcnt[i] = query(i, 1, 1, n, x, y);
      update(i, 1, 1, n, x, y, 0);
    }
    if (z == 1) {
      int cur = x;
      for (int i = 0; i < 26; i++) {
        if (!curcnt[i]) continue;
        update(i, 1, 1, n, cur, cur + curcnt[i] - 1, 1);
        cur += curcnt[i];
      }
    } else {
      int cur = x;
      for (int i = 25; i >= 0; i--) {
        if (!curcnt[i]) continue;
        update(i, 1, 1, n, cur, cur + curcnt[i] - 1, 1);
        cur += curcnt[i];
      }
    }
  }
  for (int i = 0; i < sz; i++) {
    for (int j = 0; j < 26; j++) {
      int tmp = query(j, 1, 1, n, i + 1, i + 1);
      if (tmp == 1) res += j + 'a';
    }
  }
  cout << res << "\n";
  return 0;
}