#include<bits/stdc++.h>
using namespace std;
struct nade{
int l,r,sum,tag;
}tree[30][400005];
char s[100005];
int a[100005];
int n,Q;
void puup(int x,int y){
tree[y][x].sum=tree[y][x<<1].sum+tree[y][x<<1|1].sum;
}
void pudo(int x,int y){
if(tree[y][x].tag){
tree[y][x].tag--;
tree[y][x<<1].sum=tree[y][x].tag*(tree[y][x<<1].r-tree[y][x<<1].l+1);
tree[y][x<<1|1].sum=tree[y][x].tag*(tree[y][x<<1|1].r-tree[y][x<<1|1].l+1);
tree[y][x<<1].tag=tree[y][x].tag+1;
tree[y][x<<1|1].tag=tree[y][x].tag+1;
tree[y][x].tag=0;
}
}
void build(int x,int l,int r){
for(int i=1;i<=26;i++)tree[i][x].l=l,tree[i][x].r=r;
if(l==r){
tree[s[l]-'a'+1][x].sum=1;
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
for(int i=1;i<=26;i++)puup(x,i);
}
void change(int x,int l,int r,int i,int w){
if(tree[i][x].l>=l&&tree[i][x].r<=r){
tree[i][x].sum=w*(tree[i][x].r-tree[i][x].l+1);
tree[i][x].tag=w+1;
return;
}
pudo(x,i);
if(tree[i][x<<1].r>=l)change(x<<1,l,r,i,w);
if(tree[i][x<<1|1].l<=r)change(x<<1|1,l,r,i,w);
puup(x,i);
}
int ask(int x,int l,int r,int k){
if(tree[k][x].l>=l&&tree[k][x].r<=r)return tree[k][x].sum;
pudo(x,k);
int ans=0;
if(tree[k][x<<1].r>=l)ans+=ask(x<<1,l,r,k);
if(tree[x][x<<1|1].l<=r)ans+=ask(x<<1|1,l,r,k);
puup(x,k);
return ans;
}
void get(int x,int k){
if(tree[k][x].l==tree[k][x].r){
if(tree[k][x].sum)a[tree[k][x].l]=k;
return;
}
pudo(x,k);
get(x<<1,k);get(x<<1|1,k);
puup(x,k);
}
int main(){
scanf("%d%d%s",&n,&Q,s+1);
build(1,1,n);
while(Q--){
int l,r,op;
scanf("%d%d%d",&l,&r,&op);
if(op==1){
int la=l;
for(int i=1;i<=26;i++){
int cas=ask(1,l,r,i);
if(!cas)continue;
change(1,l,r,i,0);
change(1,la,la+cas-1,i,1);
la=la+cas;
}
}
else{
int la=l;
for(int i=26;i>=1;i--){
int cas=ask(1,l,r,i);
if(!cas)continue;
change(1,l,r,i,0);
change(1,la,la+cas-1,i,1);
la=la+cas;
}
}
}
for(int i=1;i<=26;i++)get(1,i);
for(int i=1;i<=n;i++)printf("%c",a[i]+'a'-1);
}