#include <bits/stdc++.h>   using namespace std;   struct segtree {     vector<vector<int>> t;     vector<int> d;     int h, n, sz;     inline void build_node(const int& x) {       for (int j = 0; j < 26; ++j) {         t[x][j] = t[x << 1][j] + t[x << 1 | 1][j];       }     }     inline void build(int x) {       for (x /= 2; x > 0; x /= 2) {         build_node(x);       }     }     segtree(const string& s) {       sz = s.size();       h = sizeof(int) * 8 - __builtin_clz(sz);       n = 1 << h;       d = vector<int>(n << 1, 0);       t = vector<vector<int>>(n << 1, vector<int>(26, 0));       for (int i = 0; i < sz; ++i) {         ++t[i + n][s[i] -  a ];       }       for (int i = n - 1; i > 0; --i) {         build_node(i);       }     }     void apply(int x, int v) {       if (x < n) {         d[x] = v;       }     }     void fill_nodes(const vector<int>& ind, vector<int> char_count, int dir) {       for (const int& x : ind) {         for (int i = 0; i < 26; ++i) {           t[x][i] = 0;         }       }       int ch_type = (dir == 1 ? 0 : 25);       for (int i = (dir == 1 ? 0 : 0); i < ind.size(); ++i) {         int x = ind[i];         int my_sz = 1 << (h - (sizeof(int) * 8 - __builtin_clz(x)) + 1);         int have = 0;         for (; have < my_sz; (dir == 1 ? ++ch_type : --ch_type)) {           int take = min(my_sz - have, char_count[ch_type]);           t[x][ch_type] += take;           char_count[ch_type] -= take;           have += take;           if (have == my_sz) break;         }       }     }     void sort_nodes(const vector<int>& ind, int dir) {       vector<int> char_count(26, 0);       for (const int& x : ind) {         for (int i = 0; i < 26; ++i) {           char_count[i] += t[x][i];         }       }       fill_nodes(ind, char_count, dir);     }     void push_node(int x) {       if (d[x] != 0) {         fill_nodes(vector<int>({x << 1, x << 1 | 1}), t[x], d[x]);         apply(x << 1, d[x]);         apply(x << 1 | 1, d[x]);         d[x] = 0;       }     }     void push(int x) {       for (int s = h; s > 0; --s) {         int i = x >> s;         if (d[i] != 0) {           push_node(i);         }       }     }     void set(int l, int r, int dir) {       int l0 = l + n;       int r0 = r + n;       push(l0);       push(r0 - 1);       vector<int> front, back;       for (l += n, r += n; l < r; l /= 2, r /= 2) {         if (l % 2) {           front.push_back(l);           apply(l, dir);           ++l;         }         if (r % 2) {           --r;           back.push_back(r);           apply(r, dir);         }       }       reverse(back.begin(), back.end());       front.insert(front.end(), back.begin(), back.end());       sort_nodes(front, dir);       push(l0);       push(r0 - 1);       build(l0);       build(r0 - 1);     }     string to_string() {       for (int i = 1; i < n; ++i) {         push_node(i);       }       static char cstr[100010];       for (int i = 0; i < sz; ++i) {         for (int j = 0; j < 26; ++j) {           if (t[i + n][j] != 0) {             cstr[i] = j +  a ;           }         }       }       cstr[sz] = 0;       return string(cstr);     }   };   int main() {     ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);     int N, Q;     cin >> N >> Q;     string s;     cin >> s;     segtree st(s);     for (int qq = 0; qq < Q; ++qq) {       int i, j, k;       cin >> i >> j >> k;       st.set(i - 1, j, (k == 1 ? 1 : -1));     }     cout << st.to_string() <<   n ;     return 0;   }