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 Z = (int)1e5 + 111;
const int inf = (int)1e9 + 111;
const long long llinf = (long long)1e18 + 5;
const int MOD = (int)1e9 + 7;
int tSet[26][4 * Z], t[26][4 * Z];
void push(int v, int vl, int vr, int num) {
  if (tSet[num][v] != -1) {
    t[num][v] = tSet[num][v] * (vr - vl + 1);
    if (vl != vr) {
      tSet[num][2 * v + 1] = tSet[num][2 * v + 2] = tSet[num][v];
    }
    tSet[num][v] = -1;
  }
}
void modify(int v, int vl, int vr, int l, int r, int val, int num) {
  push(v, vl, vr, num);
  if (vl > r || vr < l) return;
  if (l <= vl && r >= vr) {
    tSet[num][v] = val;
    push(v, vl, vr, num);
    return;
  }
  int vm = (vl + vr) / 2;
  modify(2 * v + 1, vl, vm, l, r, val, num);
  modify(2 * v + 2, vm + 1, vr, l, r, val, num);
  t[num][v] = t[num][2 * v + 1] + t[num][2 * v + 2];
}
int query(int v, int vl, int vr, int l, int r, int num) {
  push(v, vl, vr, num);
  if (vl > r || vr < l) return 0;
  if (l <= vl && r >= vr) return t[num][v];
  int vm = (vl + vr) / 2;
  int ql = query(2 * v + 1, vl, vm, l, r, num);
  int qr = query(2 * v + 2, vm + 1, vr, l, r, num);
  return ql + qr;
}
int main() {
  ios_base::sync_with_stdio(false);
  int n, q;
  string s;
  cin >> n >> q >> s;
  for (int i = 0; i < 26; ++i) {
    for (int j = 0; j < 4 * Z; ++j) {
      tSet[i][j] = -1;
    }
  }
  for (int i = 0; i < n; ++i) {
    modify(0, 0, n - 1, i, i, 1, s[i] - 'a');
  }
  while (q--) {
    int l, r, type;
    cin >> l >> r >> type;
    l--;
    r--;
    if (type == 1) {
      int pos = l;
      for (int i = 0; i < 26; ++i) {
        int cnt = query(0, 0, n - 1, l, r, i);
        if (cnt) {
          modify(0, 0, n - 1, l, r, 0, i);
          modify(0, 0, n - 1, pos, pos + cnt - 1, 1, i);
          pos += cnt;
        }
      }
    } else {
      int pos = l;
      for (int i = 25; i >= 0; --i) {
        int cnt = query(0, 0, n - 1, l, r, i);
        if (cnt) {
          modify(0, 0, n - 1, l, r, 0, i);
          modify(0, 0, n - 1, pos, pos + cnt - 1, 1, i);
          pos += cnt;
        }
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < 26; ++j) {
      if (query(0, 0, n - 1, i, i, j)) {
        cout << char(j + 'a');
      }
    }
  }
  return 0;
}