# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
# define mp make_pair
# define CF
struct st
{
    int m[26];
    st(void)
    {
        memset(m,0,sizeof(m));
    };
};
st operator + (st a,st b)
{
    st c;
    for (int i = 0;i < 26;++i)
        c.m[i] = a.m[i] + b.m[i];
    return c;
}
void operator += (st &a,st b)
{
    a = a + b;
}
st t[1 << 20];
int lll[1 << 20];
char s[1 << 20];
void build(int p,int u,int node)
{
    lll[node] = -1;
    if (p == u) t[node].m[s[p] - 'a'] = 1;
    else
    {
        int m = (p + u) / 2;
        build(p,m,node << 1);
        build(m + 1,u,node << 1 | 1);
        t[node] = t[node << 1] + t[node << 1 | 1];
    }
}
void lazy(int p,int u,int node)
{
    if (lll[node] == -1) return;
    memset(t[node].m,0,sizeof(t[node].m));
    t[node].m[lll[node]] = u - p + 1;
    if (p != u)
        lll[node << 1] = lll[node << 1 | 1] = lll[node];
    lll[node] = -1;
}
void update(int p,int u,int l,int r,int v,int node)
{
    lazy(p,u,node);
    if (l <= p && u <= r) lll[node] = v;
    else
    {
        int m = (p + u) / 2;
        if (l <= m) update(p,m,l,r,v,node << 1);
        else lazy(p,m,node << 1);
        if (m+1<=r) update(m+1,u,l,r,v,node << 1 | 1);
        else lazy(m+1,u,node << 1 | 1);
        t[node] = t[node << 1] + t[node << 1 | 1];
    }
}
st query(int p,int u,int l,int r,int node)
{
    lazy(p,u,node);
    if (l <= p && u <= r) return t[node];
    int m = (p + u) / 2;
    st ans;
    if (l <= m) ans += query(p,m,l,r,node << 1);
    if (m+1<=r) ans += query(m+1,u,l,r,node << 1 | 1);
    return ans;
}
void go(int p,int u,int node)
{
    lazy(p,u,node);
    if (p == u)
    {
        for (int i = 0;i < 26;++i)
            if (t[node].m[i])
                s[p] = char(i + 'a');
    }
    else
    {
        int m = (p + u) / 2;
        go(p,m,node << 1);
        go(m + 1,u,node << 1 | 1);
    }
}
int main(void)
{
    #ifdef CF
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m;
    IOS;
    fi>>n>>m;
    fi>>(s + 1);
    build(1,n,1);
    while (m --)
    {
        int l,r;
        fi>>l>>r;
        auto T = query(1,n,l,r,1);
        int cnt = 0;
        for (int i = 0;i < 26;++i)
            cnt += T.m[i] & 1;
        if (cnt > 1) continue;
        for (int i = 0;i < 26;++i)
            if (!(T.m[i] & 1) && T.m[i])
            {
                const int cur = T.m[i] / 2 - 1;
                update(1,n,l,l + cur,i,1);
                update(1,n,r - cur,r,i,1);
                l += cur;++l;
                r -= cur;--r;
            }
        for (int i = 0;i < 26;++i)
            if (T.m[i] & 1)
                update(1,n,l,r,i,1);
    }
    go(1,n,1);
    fo << (s + 1) << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N = 1000 * 100 + 10, Z = 26;
int n;
string s;

struct SegmentTree {
	struct Node {
		int lazy = 0, sum = 0, l, r;
		void merge(Node L, Node R) {
			sum = L.sum + R.sum;
		}
		void init(char c, int x) {
			sum += s[x] == c;
			l = x, r = x + 1;
		}
		void add(int x) {
			if (x == -1) {
				sum = 0;
				lazy = -1;
			}
			if (x == 1) {
				sum = r - l;
				lazy = 1;
			}
		}
	} seg[N << 2];
	void build(char c, int l = 0, int r = n, int root = 1) {
		seg[root].l = l, seg[root].r = r;
		if (l + 1 == r) {
			seg[root].sum = (s[l] == c);
			return;
		}
		int mid = l + r >> 1;
		build(c, l, mid, root << 1), build(c, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void push(int root) {
		seg[root << 1].add(seg[root].lazy), seg[root << 1 | 1].add(seg[root].lazy);
		seg[root].lazy = 0;
	}
	void clear(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r) {
			seg[root].add(-1);
			return;
		}
		if (s >= r || e <= l)
			return;
		int mid = l + r >> 1;
		push(root);
		clear(s, e, l, mid, root << 1), clear(s, e, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void upd(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r) {
			seg[root].add(1);
			return;
		}
		if (s >= r || e <= l)
			return;
		push(root);
		int mid = l + r >> 1;
		upd(s, e, l, mid, root << 1), upd(s, e, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void print(char c, int l = 0, int r = n, int root = 1) {
		if (l + 1 == r) {
			if (seg[root].sum)
				s[l] = c;
			return;
		}
		push(root);
		int mid = l + r >> 1;
		print(c, l, mid, root << 1), print(c, mid, r, root << 1 | 1);
	}
	int get(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r)
			return seg[root].sum;
		if (s >= r || e <= l)
			return 0;
		push(root);
		int mid = l + r >> 1;
		return get(s, e, l, mid, root << 1) + get(s, e, mid, r, root << 1 | 1);
	}
} T[Z];

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int Q;
	cin >> n >> Q >> s;
	for (int i = 0; i < Z; i++)
		T[i].build(i + 'a');
	while (Q--) {
		int l, r;
		cin >> l >> r;
		int cnt = 0;
		--l;
		for (int i = 0; i < Z; i++)
			cnt += T[i].get(l, r) % 2;
		if (cnt <= 1) {
			int L = l, R = r;
			for (int i = 0; i < Z; i++) {
				int x = T[i].get(l, r);
				T[i].clear(l, r);
				if (x > 1) {
					T[i].upd(L, L + x / 2);
					T[i].upd(R - x / 2, R);
				}
				if (x & 1)
					T[i].upd((L + R) / 2, (L + R) / 2 + 1);
				L += x / 2, R -= x / 2;
			}
		}
	}
	for (int i = 0; i < Z; i++)
		T[i].print(i + 'a');
	cout << s << '\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N = 1000 * 100 + 10, Z = 26;
int n;
string s;

struct SegmentTree {
	struct Node {
		int lazy = 0, sum = 0, l, r;
		void merge(Node L, Node R) {
			sum = L.sum + R.sum;
		}
		void init(char c, int x) {
			sum += s[x] == c;
			l = x, r = x + 1;
		}
		void add(int x) {
			if (x == -1) {
				sum = 0;
				lazy = -1;
			}
			if (x == 1) {
				sum = r - l;
				lazy = 1;
			}
		}
	} seg[N << 2];
	void build(char c, int l = 0, int r = n, int root = 1) {
		seg[root].l = l, seg[root].r = r;
		if (l + 1 == r) {
			seg[root].sum = (s[l] == c);
			return;
		}
		int mid = l + r >> 1;
		build(c, l, mid, root << 1), build(c, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void push(int root) {
		seg[root << 1].add(seg[root].lazy), seg[root << 1 | 1].add(seg[root].lazy);
		seg[root].lazy = 0;
	}
	void clear(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r) {
			seg[root].add(-1);
			return;
		}
		if (s >= r || e <= l)
			return;
		int mid = l + r >> 1;
		push(root);
		clear(s, e, l, mid, root << 1), clear(s, e, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void upd(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r) {
			seg[root].add(1);
			return;
		}
		if (s >= r || e <= l)
			return;
		push(root);
		int mid = l + r >> 1;
		upd(s, e, l, mid, root << 1), upd(s, e, mid, r, root << 1 | 1);
		seg[root].merge(seg[root << 1], seg[root << 1 | 1]);
	}
	void print(char c, int l = 0, int r = n, int root = 1) {
		if (l + 1 == r) {
			if (seg[root].sum)
				s[l] = c;
			return;
		}
		push(root);
		int mid = l + r >> 1;
		print(c, l, mid, root << 1), print(c, mid, r, root << 1 | 1);
	}
	int get(int s, int e, int l = 0, int r = n, int root = 1) {
		if (s <= l && e >= r)
			return seg[root].sum;
		if (s >= r || e <= l)
			return 0;
		push(root);
		int mid = l + r >> 1;
		return get(s, e, l, mid, root << 1) + get(s, e, mid, r, root << 1 | 1);
	}
} T[Z];

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	int Q;
	cin >> n >> Q >> s;
	for (int i = 0; i < Z; i++)
		T[i].build(i + 'a');
	while (Q--) {
		int l, r;
		cin >> l >> r;
		int cnt = 0;
		--l;
		for (int i = 0; i < Z; i++)
			cnt += T[i].get(l, r) % 2;
		if (cnt <= 1) {
			int L = l, R = r;
			for (int i = 0; i < Z; i++) {
				int x = T[i].get(l, r);
				T[i].clear(l, r);
				if (x > 1) {
					T[i].upd(L, L + x / 2);
					T[i].upd(R - x / 2, R);
				}
				if (x & 1)
					T[i].upd((L + R) / 2, (L + R) / 2 + 1);
				L += x / 2, R -= x / 2;
			}
		}
	}
	for (int i = 0; i < Z; i++)
		T[i].print(i + 'a');
	cout << s << '\n';
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll n,m;
char s[MAX];
struct  segmentTree
{
	ll SEG[4*MAX];
	ll Lazy[4*MAX];
	void build(ll node, ll start, ll end, ll ch){
		Lazy[node]=-1;
		if(start>end) return;
		if(start==end){
			SEG[node]=((s[start]-'a')==ch)?1:0;
			return;
		}
		ll mid=(start+end)>>1;
		build(2*node, start, mid, ch);
		build(2*node+1, mid+1, end, ch);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}
	ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
		if(start>end || l>end || r<start) return 0;
		if(Lazy[node]!=-1){
			SEG[node]=(end-start+1)*Lazy[node];
			if(start!=end){
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(l<=start && r>=end){
			return SEG[node];
		}
		ll mid=(start+end)>>1;
		ll left=query(2*node, start, mid, l, r, ch);
		ll right=query(2*node+1, mid+1, end, l, r, ch);
		return (left+right);
	}
	void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
		if(Lazy[node]!=-1){
			SEG[node]=(end-start+1)*Lazy[node];
			if(start!=end){
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(start>end || l>end || r<start) return;
		if(l<=start && r>=end){
			SEG[node]=(end-start+1)*val;
			if(start!=end){
				Lazy[2*node]=val;
				Lazy[2*node+1]=val;
			}
			return;
		}
		ll mid=(start+end)>>1;
		update(2*node, start, mid, l, r, ch, val);
		update(2*node+1, mid+1, end, l, r, ch, val);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}

}seg[26];

int main(){
	freopen("input.txt", "r", stdin);
  	freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	scanf("%s", s+1);
	rep(i,0,26) seg[i].build(1LL,1LL,n,i);

	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		ll odd=0;
		ll temp[26];
		for(int i=0; i<26; i++){
			temp[i]=seg[i].query(1,1,n,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	seg[i].update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr]/2;
					len--;
					if(len>=0) seg[curr].update(1,1,n,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	seg[i].update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) seg[curr].update(1,1,n,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				seg[odd].update(1,1,n,l,r,odd,1);
			}
		}
	}
	rep(i,0,26){
		rep(j,1,n+1) if(seg[i].query(1LL,1LL,n,j,j,i)) {
			s[j]=i+'a';
		}
	}
	puts(s+1);
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) cin >> n
#define sll(n) cin >> n
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%i64d\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

int n,m;
string s;
struct  segmentTree
{
	int SEG[4*MAX];
	int Lazy[4*MAX];
	void build(int node, int start, int end, int ch){
		Lazy[node]=-1;
		if(start>end) return;
		if(start==end){
			SEG[node]=((s[start]-'a')==ch)?1:0;
			return;
		}
		int mid=(start+end)>>1;
		build(2*node, start, mid, ch);
		build(2*node+1, mid+1, end, ch);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}
	int query(int node, int start, int end, int l, int r, int ch){
		if(start>end || l>end || r<start) return 0;
		if(Lazy[node]!=-1){
			if(start!=end){
				int mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(l<=start && r>=end){
			return SEG[node];
		}
		int mid=(start+end)>>1;
		int left=query(2*node, start, mid, l, r, ch);
		int right=query(2*node+1, mid+1, end, l, r, ch);
		return (left+right);
	}
	void update(int node, int start, int end, int l, int r, int ch, int val){
		if(Lazy[node]!=-1){
			if(start!=end){
				int mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(start>end || l>end || r<start) return;
		if(l<=start && r>=end){
			SEG[node]=(end-start+1)*val;
			Lazy[node]=val;
			return;
		}
		int mid=(start+end)>>1;
		update(2*node, start, mid, l, r, ch, val);
		update(2*node+1, mid+1, end, l, r, ch, val);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}

}seg[26];

int main(){
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    //ios_base::sync_with_stdio(0);
    //cin.tie(0);
	si(n);
	si(m);
	cin >> s;
	rep(i,0,26) seg[i].build(1,0,n-1,i);

	rep(qqq,0,m){
		int l,r;
		sll(l); sll(r);
		l--;r--;
		int odd=0;
		int temp[26];
		for(int i=0; i<26; i++){
			temp[i]=seg[i].query(1,0,n-1,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					int len=temp[curr]/2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					int len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				seg[odd].update(1,0,n-1,l,r,odd,1);
			}
		}
	}

	rep(j,0,n) rep(i,0,26) if(seg[i].query(1,0,n-1,j,j,i)) {
		s[j]=i+'a';
		break;
	}

	cout << s;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[28][4*MAX];
ll Lazy[28][4*MAX];
ll n,m;
string s;
ll arr[MAX];
void build(ll node, ll start, ll end, ll ch){
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=(arr[start]==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
bool check(ll l,ll r){
	ll odd=0;
	ll even=0;
	ll temp[26];
	for(int i=0; i<26; i++){
		temp[i]=query(1,0,n-1,l,r,i);
		if(temp[i]&1) odd++;
	}
	if((r-l+1)%2==0){
		if(odd) return false;
		//update SEGTrees to get new values
		rep(i,0,26)	update(1,0,n-1,l,r,i,0);
		int curr=0;
		while(curr<26){
			ll len=temp[curr]/2;
			len--;
			if(len>=0) update(1,0,n-1,l,l+len,curr,1);
			if(len>=0) update(1,0,n-1,r-len,r,curr,1);
			curr++;
			l=l+len+1;
			r=r-len-1;
		}
		return true;
	}

	if(odd!=1) return false;
	//update SEGTrees to get new values
	rep(i,0,26)	update(1,0,n-1,l,r,i,0);
	int curr=0;
	while(curr<26){
		ll len=temp[curr];
		if(len==0 && ++curr) continue;
		if(len%2!=0){
			odd=curr;
			len--;
		}
		len/=2;
		len--;
		if(len>=0) update(1,0,n-1,l,l+len,curr,1);
		if(len>=0) update(1,0,n-1,r-len,r,curr,1);
		curr++;
		l=l+len+1;
		r=r-len-1;
	}
	update(1,0,n-1,l,r,odd,1);
	return true;
}
int main(){
	memset(Lazy,-1,sizeof(Lazy));
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	cin >> s;
	rep(i,0,s.length()){
		arr[i]=s[i]-'a';
	}
	rep(i,0,26) build(1LL,0LL,n-1LL,i);
	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		check(l,r);
	}
	rep(i,0,26){
		rep(j,0,s.length()) if(query(1LL,0LL,n-1LL,j,j,i)) {
			s[j]=i+'a';
		}
	}
	cout << s << endl;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[28][4*MAX];
ll Lazy[28][4*MAX];
ll n,m;
string s;
ll arr[MAX];
void build(ll node, ll start, ll end, ll ch){
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=(arr[start]==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
bool check(ll l,ll r){
	ll odd=0;
	ll even=0;
	ll temp[26];
	for(int i=0; i<26; i++){
		temp[i]=query(1,0,n-1,l,r,i);
		if((temp[i]%2)==0) even++;
		else odd++;
	}
	if((r-l+1)%2==0){
		if(odd) return false;
		//update SEGTrees to get new values
		rep(i,0,26)	update(1,0,n-1,l,r,i,0);
		int curr=0;
		while(l<=r){
			ll len=temp[curr]/2;
			len--;
			if(len>=0) update(1,0,n-1,l,l+len,curr,1);
			if(len>=0) update(1,0,n-1,r-len,r,curr,1);
			curr++;
			l=l+len+1;
			r=r-len-1;
		}
		return true;
	}
	if(odd!=1) return false;
	//update SEGTrees to get new values
	rep(i,0,26)	{
		update(1,0,n-1,l,r,i,0);
	}
	int curr=0;
	while(curr<26){

		ll len=temp[curr];
		if(len==0 && ++curr) continue;
		if(len%2!=0){
			odd=curr;
			curr++;
			continue;
		}
		len/=2;
		len--;
		if(len>=0) update(1,0,n-1,l,l+len,curr,1);
		if(len>=0) update(1,0,n-1,r-len,r,curr,1);
		curr++;
		l=l+len+1;
		r=r-len-1;
	}
	update(1,0,n-1,l,r,odd,1);
	return true;
}
int main(){
	memset(Lazy,-1,sizeof(Lazy));
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	cin >> s;
	rep(i,0,s.length()){
		arr[i]=s[i]-'a';
	}
	rep(i,0,26) build(1LL,0LL,n-1LL,i);
	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		check(l,r);

	}
	rep(i,0,26){
		rep(j,0,s.length()-1) if(query(1LL,0LL,n-1LL,j,j,i)) {
			s[j]=i+'a';
		}
	}
	cout << s << endl;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll n,m;
char s[MAX];
struct  segmentTree
{
	ll SEG[4*MAX];
	ll Lazy[4*MAX];
	void build(ll node, ll start, ll end, ll ch){
		Lazy[node]=-1;
		if(start>end) return;
		if(start==end){
			SEG[node]=((s[start]-'a')==ch)?1:0;
			return;
		}
		ll mid=(start+end)>>1;
		build(2*node, start, mid, ch);
		build(2*node+1, mid+1, end, ch);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}
	ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
		if(start>end || l>end || r<start) return 0;
		if(Lazy[node]!=-1){
			if(start!=end){
				ll mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(l<=start && r>=end){
			return SEG[node];
		}
		ll mid=(start+end)>>1;
		ll left=query(2*node, start, mid, l, r, ch);
		ll right=query(2*node+1, mid+1, end, l, r, ch);
		return (left+right);
	}
	void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
		if(Lazy[node]!=-1){
			if(start!=end){
				ll mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(start>end || l>end || r<start) return;
		if(l<=start && r>=end){
			SEG[node]=(end-start+1)*val;
			Lazy[node]=val;
			return;
		}
		ll mid=(start+end)>>1;
		update(2*node, start, mid, l, r, ch, val);
		update(2*node+1, mid+1, end, l, r, ch, val);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}

}seg[26];

int main(){
	freopen("input.txt", "r", stdin);
  	freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	scanf("%s", s+1);
	rep(i,0,26) seg[i].build(1LL,1LL,n,i);

	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		ll odd=0;
		ll temp[26];
		for(int i=0; i<26; i++){
			temp[i]=seg[i].query(1,1,n,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	seg[i].update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr]/2;
					len--;
					if(len>=0) seg[curr].update(1,1,n,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	seg[i].update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) seg[curr].update(1,1,n,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				seg[odd].update(1,1,n,l,r,odd,1);
			}
		}
	}

	rep(j,1,n+1) rep(i,0,26) if(seg[i].query(1LL,1LL,n,j,j,i)) {
		s[j]=i+'a';
		break;
	}

	puts(s+1);
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[26][4*MAX];
ll Lazy[26][4*MAX];
ll n,m;
char s[MAX];
string ip()
{
    string i="";
    int temp=getchar();
    while(temp<'a'||temp>'z')
        temp=getchar();
    while(temp>='a'&&temp<='z')
    {
        i+=(char)temp;
        temp=getchar();
    }
    return i;
}
void build(ll node, ll start, ll end, ll ch){
	Lazy[ch][node]=-1;
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=((s[start]-'a')==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
int main(){
	 freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	scanf("%s", s+1);
	rep(i,0,26) build(1LL,1LL,n,i);

	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		//check(l,r);
		ll odd=0;
		ll temp[26];
		for(int i=0; i<26; i++){
			temp[i]=query(1,1,n,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr]/2;
					len--;
					if(len>=0) update(1,1,n,l,l+len,curr,1);
					if(len>=0) update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	update(1,1,n,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) update(1,1,n,l,l+len,curr,1);
					if(len>=0) update(1,1,n,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				update(1,1,n,l,r,odd,1);
			}
		}
	}
	rep(i,0,26){
		rep(j,1,n+1) if(query(1LL,1LL,n,j,j,i)) {
			s[j]=i+'a';
		}
	}
	puts(s+1);
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[26][4*MAX];
ll Lazy[26][4*MAX];
ll n,m;
char s[MAX];
string ip()
{
    string i="";
    int temp=getchar();
    while(temp<'a'||temp>'z')
        temp=getchar();
    while(temp>='a'&&temp<='z')
    {
        i+=(char)temp;
        temp=getchar();
    }
    return i;
}
void build(ll node, ll start, ll end, ll ch){
	Lazy[ch][node]=-1;
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=((s[start]-'0')==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
bool check(ll l,ll r){
	ll odd=0;
	ll even=0;
	ll temp[26];
	for(int i=0; i<26; i++){
		temp[i]=query(1,0,n-1,l,r,i);
		if(temp[i]&1) odd++;
	}
	if((r-l+1)%2==0){
		if(odd) return false;
		//update SEGTrees to get new values
		rep(i,0,26)	update(1,0,n-1,l,r,i,0);
		int curr=0;
		while(curr<26){
			ll len=temp[curr]/2;
			len--;
			if(len>=0) update(1,0,n-1,l,l+len,curr,1);
			if(len>=0) update(1,0,n-1,r-len,r,curr,1);
			curr++;
			l=l+len+1;
			r=r-len-1;
		}
		return true;
	}

	if(odd!=1) return false;
	//update SEGTrees to get new values
	rep(i,0,26)	update(1,0,n-1,l,r,i,0);
	int curr=0;
	while(curr<26){
		ll len=temp[curr];
		if(len==0 && ++curr) continue;
		if(len%2!=0){
			odd=curr;
			len--;
		}
		len/=2;
		len--;
		if(len>=0) update(1,0,n-1,l,l+len,curr,1);
		if(len>=0) update(1,0,n-1,r-len,r,curr,1);
		curr++;
		l=l+len+1;
		r=r-len-1;
	}
	update(1,0,n-1,l,r,odd,1);
	return true;
}
int main(){
	 freopen("input.txt", "r", stdin);
     freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	//cin >> s;
	scanf("%s", s+1);
	rep(i,0,26) build(1LL,0LL,n-1LL,i);
	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		check(l,r);
	}
	rep(i,0,26){
		rep(j,0,n) if(query(1LL,0LL,n-1LL,j,j,i)) {
			s[j]=i+'a';
		}
	}
	puts(s+1);
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[28][4*MAX];
ll Lazy[28][4*MAX];
ll n,m;
string s;
ll arr[MAX];
void build(ll node, ll start, ll end, ll ch){
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=(arr[start]==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
bool check(ll l,ll r){
	ll odd=0;
	ll even=0;
	ll temp[26];
	for(int i=0; i<26; i++){
		temp[i]=query(1,0,n-1,l,r,i);
		if((temp[i]%2)==0) even++;
		else odd++;
	}
	if((r-l+1)%2==0){
		if(odd) return false;
		//update SEGTrees to get new values
		rep(i,0,26)	update(1,0,n-1,l,r,i,0);
		int curr=0;
		while(l<=r){
			ll len=temp[curr]/2;
			len--;
			if(len>=0) update(1,0,n-1,l,l+len,curr,1);
			if(len>=0) update(1,0,n-1,r-len,r,curr,1);
			curr++;
			l=l+len+1;
			r=r-len-1;
		}
		return true;
	}
	if(odd!=1) return false;
	//update SEGTrees to get new values
	rep(i,0,26)	{
		update(1,0,n-1,l,r,i,0);
	}
	int curr=0;
	while(curr<26){

		ll len=temp[curr];
		if(len==0 && ++curr) continue;
		if(len%2!=0){
			odd=curr;
			curr++;
			continue;
		}
		len/=2;
		len--;
		if(len>=0) update(1,0,n-1,l,l+len,curr,1);
		if(len>=0) update(1,0,n-1,r-len,r,curr,1);
		curr++;
		l=l+len+1;
		r=r-len-1;
	}
	update(1,0,n-1,l,r,odd,1);
	return true;
}
int main(){
	memset(Lazy,-1,sizeof(Lazy));
	freopen("inputf.in", "r", stdin);
	freopen("outputf.in", "w", stdout);
	sll(n);
	sll(m);
	cin >> s;
	rep(i,0,s.length()){
		arr[i]=s[i]-'a';
	}
	rep(i,0,26) build(1LL,0LL,n-1LL,i);
	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		check(l,r);

	}
	rep(i,0,26){
		rep(j,0,s.length()-1) if(query(1LL,0LL,n-1LL,j,j,i)) {
			s[j]=i+'a';
		}
	}
	cout << s << endl;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) cin >> n
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll n,m;
string s;
struct  segmentTree
{
	ll SEG[4*MAX];
	ll Lazy[4*MAX];
	void build(ll node, ll start, ll end, ll ch){
		Lazy[node]=-1;
		if(start>end) return;
		if(start==end){
			SEG[node]=((s[start]-'a')==ch)?1:0;
			return;
		}
		ll mid=(start+end)>>1;
		build(2*node, start, mid, ch);
		build(2*node+1, mid+1, end, ch);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}
	ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
		if(start>end || l>end || r<start) return 0;
		if(Lazy[node]!=-1){
			if(start!=end){
				ll mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(l<=start && r>=end){
			return SEG[node];
		}
		ll mid=(start+end)>>1;
		ll left=query(2*node, start, mid, l, r, ch);
		ll right=query(2*node+1, mid+1, end, l, r, ch);
		return (left+right);
	}
	void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
		if(Lazy[node]!=-1){
			if(start!=end){
				ll mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(start>end || l>end || r<start) return;
		if(l<=start && r>=end){
			SEG[node]=(end-start+1)*val;
			Lazy[node]=val;
			return;
		}
		ll mid=(start+end)>>1;
		update(2*node, start, mid, l, r, ch, val);
		update(2*node+1, mid+1, end, l, r, ch, val);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}

}seg[26];

int main(){
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
	sll(n);
	sll(m);
	cin >> s;
	rep(i,0,26) seg[i].build(1LL,0LL,n-1,i);

	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		ll odd=0;
		ll temp[26];
		for(int i=0; i<26; i++){
			temp[i]=seg[i].query(1,0,n-1,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr]/2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					ll len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				seg[odd].update(1,0,n-1,l,r,odd,1);
			}
		}
	}

	rep(j,0,n) rep(i,0,26) if(seg[i].query(1LL,0,n-1,j,j,i)) {
		s[j]=i+'a';
		break;
	}

	cout << s;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%lld\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

ll SEG[28][4*MAX];
ll Lazy[28][4*MAX];
ll n,m;
string s;
ll arr[MAX];
void build(ll node, ll start, ll end, ll ch){
	if(start>end) return;
	if(start==end){
		SEG[ch][node]=(arr[start]==ch)?1:0;
		return;
	}
	ll mid=(start+end)>>1;
	build(2*node, start, mid, ch);
	build(2*node+1, mid+1, end, ch);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
ll query(ll node, ll start, ll end, ll l, ll r, ll ch){
	if(start>end || l>end || r<start) return 0;
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(l<=start && r>=end){
		return SEG[ch][node];
	}
	ll mid=(start+end)>>1;
	ll left=query(2*node, start, mid, l, r, ch);
	ll right=query(2*node+1, mid+1, end, l, r, ch);
	return (left+right);
}
void update(ll node, ll start, ll end, ll l, ll r, ll ch, ll val){
	if(Lazy[ch][node]!=-1){
		SEG[ch][node]=(end-start+1)*Lazy[ch][node];
		if(start!=end){
			Lazy[ch][2*node]=Lazy[ch][node];
			Lazy[ch][2*node+1]=Lazy[ch][node];
		}
		Lazy[ch][node]=-1;
	}
	if(start>end || l>end || r<start) return;
	if(l<=start && r>=end){
		SEG[ch][node]=(end-start+1)*val;
		if(start!=end){
			Lazy[ch][2*node]=val;
			Lazy[ch][2*node+1]=val;
		}
		return;
	}
	ll mid=(start+end)>>1;
	update(2*node, start, mid, l, r, ch, val);
	update(2*node+1, mid+1, end, l, r, ch, val);
	SEG[ch][node]=SEG[ch][2*node]+SEG[ch][2*node+1];
	return;
}
bool check(ll l,ll r){
	ll odd=0;
	ll even=0;
	ll temp[26];
	for(int i=0; i<26; i++){
		temp[i]=query(1,0,n-1,l,r,i);
		if((temp[i]%2)==0) even++;
		else odd++;
	}
	if((r-l+1)%2==0){
		if(odd) return false;
		//update SEGTrees to get new values
		rep(i,0,26)	update(1,0,n-1,l,r,i,0);
		int curr=0;
		while(curr<26){
			ll len=temp[curr]/2;
			len--;
			if(len>=0) update(1,0,n-1,l,l+len,curr,1);
			if(len>=0) update(1,0,n-1,r-len,r,curr,1);
			curr++;
			l=l+len+1;
			r=r-len-1;
		}
		return true;
	}

	if(odd!=1) return false;
	//update SEGTrees to get new values
	rep(i,0,26)	update(1,0,n-1,l,r,i,0);
	int curr=0;
	while(curr<26){
		ll len=temp[curr];
		if(len==0 && ++curr) continue;
		if(len%2!=0){
			odd=curr;
			curr++;
			continue;
		}
		len/=2;
		len--;
		if(len>=0) update(1,0,n-1,l,l+len,curr,1);
		if(len>=0) update(1,0,n-1,r-len,r,curr,1);
		curr++;
		l=l+len+1;
		r=r-len-1;
	}
	update(1,0,n-1,l,r,odd,1);
	return true;
}
int main(){
	memset(Lazy,-1,sizeof(Lazy));
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
	sll(n);
	sll(m);
	cin >> s;
	rep(i,0,s.length()){
		arr[i]=s[i]-'a';
	}
	rep(i,0,26) build(1LL,0LL,n-1LL,i);
	rep(qqq,0,m){
		ll l,r;
		sll(l); sll(r);
		l--;r--;
		check(l,r);
	}
	rep(i,0,26){
		rep(j,0,s.length()) if(query(1LL,0LL,n-1LL,j,j,i)) {
			s[j]=i+'a';
		}
	}
	cout << s << endl;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <iostream>
#include <cmath>
#include <climits>
#include <cstring>
using namespace std;
#define ll long long
#define si(n) cin >> n
#define sll(n) cin >> n
#define pin(n) printf("%d\n",n)
#define plln(n) printf("%i64d\n",n)
#define pis(n) printf("%d ",n)
#define plls(n) printf("%lld ",n)
#define rep(i, start, end) for(int i=start; i<end; i++)
#define S second
#define F first
#define P pair<int,int>
#define PP pair<P,int>
#define mod 1000000007
#define MAX 100005
#define newLine printf("\n")

int n,m;
string s;
struct  segmentTree
{
	int SEG[4*MAX];
	int Lazy[4*MAX];
	void build(int node, int start, int end, int ch){
		Lazy[node]=-1;
		if(start>end) return;
		if(start==end){
			SEG[node]=((s[start]-'a')==ch)?1:0;
			return;
		}
		int mid=(start+end)>>1;
		build(2*node, start, mid, ch);
		build(2*node+1, mid+1, end, ch);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}
	int query(int node, int start, int end, int l, int r, int ch){
		if(start>end || l>end || r<start) return 0;
		if(Lazy[node]!=-1){
			if(start!=end){
				int mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(l<=start && r>=end){
			return SEG[node];
		}
		int mid=(start+end)>>1;
		int left=query(2*node, start, mid, l, r, ch);
		int right=query(2*node+1, mid+1, end, l, r, ch);
		return (left+right);
	}
	void update(int node, int start, int end, int l, int r, int ch, int val){
		if(Lazy[node]!=-1){
			if(start!=end){
				int mid=(start+end)>>1;
				SEG[2*node]=(mid-start+1)*Lazy[node];
				SEG[2*node+1]=(end-mid)*Lazy[node];
				Lazy[2*node]=Lazy[node];
				Lazy[2*node+1]=Lazy[node];
			}
			Lazy[node]=-1;
		}
		if(start>end || l>end || r<start) return;
		if(l<=start && r>=end){
			SEG[node]=(end-start+1)*val;
			Lazy[node]=val;
			return;
		}
		int mid=(start+end)>>1;
		update(2*node, start, mid, l, r, ch, val);
		update(2*node+1, mid+1, end, l, r, ch, val);
		SEG[node]=SEG[2*node]+SEG[2*node+1];
		return;
	}

}seg[26];

int main(){
	freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
	si(n);
	si(m);
	cin >> s;
	rep(i,0,26) seg[i].build(1,0,n-1,i);

	rep(qqq,0,m){
		int l,r;
		sll(l); sll(r);
		l--;r--;
		int odd=0;
		int temp[26];
		for(int i=0; i<26; i++){
			temp[i]=seg[i].query(1,0,n-1,l,r,i);
			if(temp[i]&1) odd++;
		}
		if((l-r+1)%2==0){
			if(odd==0){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					int len=temp[curr]/2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
			}
		}
		else{
			if(odd==1){
				rep(i,0,26)	seg[i].update(1,0,n-1,l,r,i,0);
				int curr=0;
				while(curr<26){
					int len=temp[curr];
					if(len==0 && ++curr) continue;
					if(len%2!=0){
						odd=curr;
						len--;
					}
					len/=2;
					len--;
					if(len>=0) seg[curr].update(1,0,n-1,l,l+len,curr,1);
					if(len>=0) seg[curr].update(1,0,n-1,r-len,r,curr,1);
					curr++;
					l=l+len+1;
					r=r-len-1;
				}
				seg[odd].update(1,0,n-1,l,r,odd,1);
			}
		}
	}

	rep(j,0,n) rep(i,0,26) if(seg[i].query(1,0,n-1,j,j,i)) {
		s[j]=i+'a';
		break;
	}

	cout << s;
	//cout << 26*log2(1e5)*(1e5) << endl;
	return 0;
}


#include <fstream>
#include <vector>

using namespace std;

vector< vector<int> > T(26), L(26);
int l, size;

void Stworz(int n)
{
    int p = 1;
    while (p < n)
        p *= 2;
    l = p;
    size = 2 * p - 1;
    for (int i = 0; i < 26; ++i)
    {
        for (int j = 0; j <= size; ++j)
        {
            T[i].push_back(0);
            L[i].push_back(-1);
        }
    }
}

void Propaguj(int c, int a, int dl)
{
    if (L[c][a] == -1)
        return;
    T[c][2 * a] = dl / 2 * L[c][a];
    T[c][2 * a + 1] = dl / 2 * L[c][a];
    L[c][2 * a] = L[c][a];
    L[c][2 * a + 1] = L[c][a];
    L[c][a] = -1;
}

void Ustaw(int c, int a, int Le, int Pr, int l, int p, int x)
{
    if (Le == l && Pr == p)
    {
        T[c][a] = x * (Pr - Le + 1);
        L[c][a] = x;
        return;
    }
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    if (max(Le, l) <= min(S, p))
        Ustaw(c, 2 * a, Le, S, max(Le, l), min(S, p), x);
    if (max(S + 1, l) <= min(Pr, p))
        Ustaw(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p), x);
    T[c][a] = T[c][2 * a] + T[c][2 * a + 1];
}

int Suma(int c, int a, int Le, int Pr, int l, int p)
{
    if (Le == l && Pr == p)
        return T[c][a];
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    int s = 0;
    if (max(Le, l) <= min(S, p))
        s += Suma(c, 2 * a, Le, S, max(Le, l), min(S, p));
    if (max(S + 1, l) <= min(Pr, p))
        s += Suma(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p));
    return s;
}

int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n, m;
    string a;
    cin >> n >> m >> a;
    Stworz(n);
    for (int i = 0; i < n; ++i)
        Ustaw(a[i] - 'a', 1, 0, size - l, i, i, 1);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        cin >> l >> r;
        --l;
        --r;
        vector<int> wyst(26, 0);
        int ilNparz = 0;
        for (int j = 0; j < 26; ++j)
        {
            wyst[j] = Suma(j, 1, 0, size - ::l, l, r);
            if (wyst[j] % 2 == 1)
                ++ilNparz;
        }
        if (ilNparz >= 2)
            continue;
        for (int j = 0; j < 26; ++j)
            Ustaw(j, 1, 0, size - ::l, l, r, 0);
        if ((r - l + 1) % 2 == 1)
        {
            int nparz;
            for (int j = 0; j < 26; ++j)
                if (wyst[j] % 2 == 1)
                    nparz = j;
            Ustaw(nparz, 1, 0, size - ::l, (l + r) / 2, (l + r) / 2, 1);
            --wyst[nparz];
        }
        int pocz, kon = l - 1;
        for (int j = 0; j < 26; ++j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] / 2 - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] /= 2;
        }
        kon = (l + r) / 2;
        for (int j = 25; j >= 0; --j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] = 0;
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < 26; ++j)
        {
            if (Suma(j, 1, 0, size - l, i, i) == 1)
            {
                cout << (char) (j + 'a');
                break;
            }
        }
    }
    return 0;
}


#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

vector< vector<int> > T(26), L(26);
int l, size;

void Stworz(int n)
{
    int p = 1;
    while (p < n)
        p *= 2;
    l = p;
    size = 2 * p - 1;
    for (int i = 0; i < 26; ++i)
    {
        for (int j = 0; j <= size; ++j)
        {
            T[i].push_back(0);
            L[i].push_back(-1);
        }
    }
}

void Propaguj(int c, int a, int dl)
{
    if (L[c][a] == -1)
        return;
    T[c][2 * a] = dl / 2 * L[c][a];
    T[c][2 * a + 1] = dl / 2 * L[c][a];
    L[c][2 * a] = L[c][a];
    L[c][2 * a + 1] = L[c][a];
    L[c][a] = -1;
}

void Ustaw(int c, int a, int Le, int Pr, int l, int p, int x)
{
    if (Le == l && Pr == p)
    {
        T[c][a] = x * (Pr - Le + 1);
        L[c][a] = x;
        return;
    }
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    if (max(Le, l) <= min(S, p))
        Ustaw(c, 2 * a, Le, S, max(Le, l), min(S, p), x);
    if (max(S + 1, l) <= min(Pr, p))
        Ustaw(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p), x);
    T[c][a] = T[c][2 * a] + T[c][2 * a + 1];
}

int Suma(int c, int a, int Le, int Pr, int l, int p)
{
    if (Le == l && Pr == p)
        return T[c][a];
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    int s = 0;
    if (max(Le, l) <= min(S, p))
        s += Suma(c, 2 * a, Le, S, max(Le, l), min(S, p));
    if (max(S + 1, l) <= min(Pr, p))
        s += Suma(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p));
    return s;
}

int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n, m;
    char a[100010];
    scanf("%d %d", &n, &m);
    scanf("%s", a);
    Stworz(n);
    for (int i = 0; i < n; ++i)
        Ustaw(a[i] - 'a', 1, 0, size - l, i, i, 1);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        --l;
        --r;
        vector<int> wyst(26, 0);
        int ilNparz = 0;
        for (int j = 0; j < 26; ++j)
        {
            wyst[j] = Suma(j, 1, 0, size - ::l, l, r);
            if (wyst[j] % 2 == 1)
                ++ilNparz;
        }
        if (ilNparz >= 2)
            continue;
        for (int j = 0; j < 26; ++j)
            Ustaw(j, 1, 0, size - ::l, l, r, 0);
        if ((r - l + 1) % 2 == 1)
        {
            int nparz;
            for (int j = 0; j < 26; ++j)
                if (wyst[j] % 2 == 1)
                    nparz = j;
            Ustaw(nparz, 1, 0, size - ::l, (l + r) / 2, (l + r) / 2, 1);
            --wyst[nparz];
        }
        int pocz, kon = l - 1;
        for (int j = 0; j < 26; ++j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] / 2 - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] /= 2;
        }
        kon = (l + r) / 2;
        for (int j = 25; j >= 0; --j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] = 0;
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < 26; ++j)
        {
            if (Suma(j, 1, 0, size - l, i, i) == 1)
            {
                printf("%c", (char) (j + 'a'));
                break;
            }
        }
    }
    return 0;
}


#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

vector< vector<int> > T(26), L(26);
int l, size;

void Stworz(int n)
{
    int p = 1;
    while (p < n)
        p *= 2;
    l = p;
    size = 2 * p - 1;
    for (int i = 0; i < 26; ++i)
    {
        for (int j = 0; j <= size; ++j)
        {
            T[i].push_back(0);
            L[i].push_back(-1);
        }
    }
}

void Propaguj(int c, int a, int dl)
{
    if (L[c][a] == -1)
        return;
    T[c][2 * a] = dl / 2 * L[c][a];
    T[c][2 * a + 1] = dl / 2 * L[c][a];
    L[c][2 * a] = L[c][a];
    L[c][2 * a + 1] = L[c][a];
    L[c][a] = -1;
}

void Ustaw(int c, int a, int Le, int Pr, int l, int p, int x)
{
    if (Le == l && Pr == p)
    {
        T[c][a] = x * (Pr - Le + 1);
        L[c][a] = x;
        return;
    }
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    if (max(Le, l) <= min(S, p))
        Ustaw(c, 2 * a, Le, S, max(Le, l), min(S, p), x);
    if (max(S + 1, l) <= min(Pr, p))
        Ustaw(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p), x);
    T[c][a] = T[c][2 * a] + T[c][2 * a + 1];
}

int Suma(int c, int a, int Le, int Pr, int l, int p)
{
    if (Le == l && Pr == p)
        return T[c][a];
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    int s = 0;
    if (max(Le, l) <= min(S, p))
        s += Suma(c, 2 * a, Le, S, max(Le, l), min(S, p));
    if (max(S + 1, l) <= min(Pr, p))
        s += Suma(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p));
    return s;
}

int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n, m;
    string a;
    cin >> n >> m >> a;
    Stworz(n);
    for (int i = 0; i < n; ++i)
        Ustaw(a[i] - 'a', 1, 0, size - l, i, i, 1);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        cin >> l >> r;
        --l;
        --r;
        vector<int> wyst(26, 0);
        int ilNparz = 0;
        for (int j = 0; j < 26; ++j)
        {
            wyst[j] = Suma(j, 1, 0, size - ::l, l, r);
            if (wyst[j] % 2 == 1)
                ++ilNparz;
        }
        if (ilNparz >= 2)
            continue;
        for (int j = 0; j < 26; ++j)
            Ustaw(j, 1, 0, size - ::l, l, r, 0);
        if ((r - l + 1) % 2 == 1)
        {
            int nparz;
            for (int j = 0; j < 26; ++j)
                if (wyst[j] % 2 == 1)
                    nparz = j;
            Ustaw(nparz, 1, 0, size - ::l, (l + r) / 2, (l + r) / 2, 1);
            --wyst[nparz];
        }
        int pocz, kon = l - 1;
        for (int j = 0; j < 26; ++j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] / 2 - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] /= 2;
        }
        kon = (l + r) / 2;
        for (int j = 25; j >= 0; --j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] = 0;
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < 26; ++j)
        {
            if (Suma(j, 1, 0, size - l, i, i) == 1)
            {
                cout << (char) (j + 'a');
                break;
            }
        }
    }
    return 0;
}


#include <iostream>
#include <vector>

using namespace std;

vector< vector<int> > T(26), L(26);
int l, size;

void Stworz(int n)
{
    int p = 1;
    while (p < n)
        p *= 2;
    l = p;
    size = 2 * p - 1;
    for (int i = 0; i < 26; ++i)
    {
        for (int j = 0; j <= size; ++j)
        {
            T[i].push_back(0);
            L[i].push_back(-1);
        }
    }
}

void Propaguj(int c, int a, int dl)
{
    if (L[c][a] == -1)
        return;
    T[c][2 * a] = dl / 2 * L[c][a];
    T[c][2 * a + 1] = dl / 2 * L[c][a];
    L[c][2 * a] = L[c][a];
    L[c][2 * a + 1] = L[c][a];
    L[c][a] = -1;
}

void Ustaw(int c, int a, int Le, int Pr, int l, int p, int x)
{
    if (Le == l && Pr == p)
    {
        T[c][a] = x * (Pr - Le + 1);
        L[c][a] = x;
        return;
    }
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    if (max(Le, l) <= min(S, p))
        Ustaw(c, 2 * a, Le, S, max(Le, l), min(S, p), x);
    if (max(S + 1, l) <= min(Pr, p))
        Ustaw(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p), x);
    T[c][a] = T[c][2 * a] + T[c][2 * a + 1];
}

int Suma(int c, int a, int Le, int Pr, int l, int p)
{
    if (Le == l && Pr == p)
        return T[c][a];
    Propaguj(c, a, Pr - Le + 1);
    int S = Le + (Pr - Le) / 2;
    int s = 0;
    if (max(Le, l) <= min(S, p))
        s += Suma(c, 2 * a, Le, S, max(Le, l), min(S, p));
    if (max(S + 1, l) <= min(Pr, p))
        s += Suma(c, 2 * a + 1, S + 1, Pr, max(S + 1, l), min(Pr, p));
    return s;
}

int main()
{
    ios_base::sync_with_stdio(0);
    int n, m;
    string a;
    cin >> n >> m >> a;
    Stworz(n);
    for (int i = 0; i < n; ++i)
        Ustaw(a[i] - 'a', 1, 0, size - l, i, i, 1);
    for (int i = 0; i < m; ++i)
    {
        int l, r;
        cin >> l >> r;
        --l;
        --r;
        vector<int> wyst(26, 0);
        int ilNparz = 0;
        for (int j = 0; j < 26; ++j)
        {
            wyst[j] = Suma(j, 1, 0, size - ::l, l, r);
            if (wyst[j] % 2 == 1)
                ++ilNparz;
        }
        if (ilNparz >= 2)
            continue;
        for (int j = 0; j < 26; ++j)
            Ustaw(j, 1, 0, size - ::l, l, r, 0);
        if ((r - l + 1) % 2 == 1)
        {
            int nparz;
            for (int j = 0; j < 26; ++j)
                if (wyst[j] % 2 == 1)
                    nparz = j;
            Ustaw(nparz, 1, 0, size - ::l, (l + r) / 2, (l + r) / 2, 1);
            --wyst[nparz];
        }
        int pocz, kon = l - 1;
        for (int j = 0; j < 26; ++j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] / 2 - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] /= 2;
        }
        kon = (l + r) / 2;
        for (int j = 25; j >= 0; --j)
        {
            if (wyst[j] == 0)
                continue;
            pocz = kon + 1;
            kon = pocz + wyst[j] - 1;
            Ustaw(j, 1, 0, size - ::l, pocz, kon, 1);
            wyst[j] = 0;
        }
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < 26; ++j)
        {
            if (Suma(j, 1, 0, size - l, i, i) == 1)
            {
                cout << (char) (j + 'a');
                break;
            }
        }
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pll pair <ll , ll>

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair

#define X first
#define Y second

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)

#define ll int

const ll MAXN=1e5+10;

struct node
{
    ll val , lazy;
    bool zero;

    node()
    {
        val=0;
        lazy=0;
        zero=false;
    }
};

node segt[26][4*MAXN];

ll a[26];

void lzu(ll main_id , ll id)
{
    if (segt[main_id][id].zero)
    {
        segt[main_id][2*id+1].zero=true;
        segt[main_id][2*id+2].zero=true;

        segt[main_id][2*id+1].val=0;
        segt[main_id][2*id+2].val=0;

        segt[main_id][2*id+1].lazy=0;
        segt[main_id][2*id+2].lazy=0;
    }

    segt[main_id][2*id+1].val+=segt[main_id][id].lazy;
    segt[main_id][2*id+2].val+=segt[main_id][id].lazy;

    segt[main_id][2*id+1].lazy+=segt[main_id][id].lazy;
    segt[main_id][2*id+2].lazy+=segt[main_id][id].lazy;

    segt[main_id][id].lazy=0;
    segt[main_id][id].zero=false;
}

void update(ll main_id , ll id , ll L , ll R , ll l , ll r , ll d)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val+=d;
        segt[main_id][id].lazy+=d;

        return;
    }

    lzu(main_id , id);

    ll mid=(L+R)/2;

    update(main_id , 2*id+1 , L , mid , l , r , d);
    update(main_id , 2*id+2 , mid+1 , R , l , r , d);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

void zero_update(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val=0;
        segt[main_id][id].lazy=0;
        segt[main_id][id].zero=true;

        return;
    }

    lzu(main_id , id);

    ll mid=(L+R)/2;

    zero_update(main_id , 2*id+1 , L , mid , l , r);
    zero_update(main_id , 2*id+2 , mid+1 , R , l , r);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

ll get_res(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return 0;
    }

    if (L>=l && R<=r)
    {
        return segt[main_id][id].val;
    }

    lzu(main_id , id);

    ll mid=(L+R)/2;

    return get_res(main_id , 2*id+1 , L , mid , l , r)+get_res(main_id , 2*id+2 , mid+1 , R , l , r);
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

	ll n , q;
	fin>>n>>q;

	for(ll i=0;i<n;i++)
    {
        char x;
        fin>>x;

        update(x-'a' , 0 , 0 , n-1 , i , i , 1);
    }

    for(ll i=0;i<q;i++)
    {
        ll l , r , o=-1;
        fin>>l>>r;

        l--;
        r--;

        bool flag=false;

        for(ll j=0;j<26;j++)
        {
            a[j]=get_res(j , 0 , 0 , n-1 , l , r);

            if (a[j]&1)
            {
                if (o==-1)
                {
                    o=j;
                }
                else
                {
                    flag=true;
                }
            }
        }

        if (!flag)
        {
            for(ll j=0;j<26;j++)
            {
                zero_update(j , 0 , 0 , n-1 , l , r);
            }

            if (o!=-1)
            {
                update(o , 0 , 0 , n-1 , l+(r-l+1)/2 , l+(r-l+1)/2 , 1);

                update(o , 0 , 0 , n-1 , l , l+(a[o]/2)-1 , 1);
                l+=a[o]/2;

                update(o , 0 , 0 , n-1 , r-(a[o]/2)+1 , r , 1);
                r-=a[o]/2;
            }

            for(ll j=0;j<26;j++)
            {
                if (a[j]>0 && j!=o)
                {
                    update(j , 0 , 0 , n-1 , l , l+(a[j]/2)-1 , 1);
                    l+=a[j]/2;

                    update(j , 0 , 0 , n-1 , r-(a[j]/2)+1 , r , 1);
                    r-=a[j]/2;
                }

                a[j]=0;
            }
        }
    }

    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<26;j++)
        {
            if (get_res(j , 0 , 0 , n-1 , i , i))
            {
                fout<<char('a'+j);
                break;
            }
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pll pair <ll , ll>

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair

#define X first
#define Y second

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)

#define ll int

const ll MAXN=1e5+10;

struct node
{
    ll val , lazy;
    bool zero;

    node()
    {
        val=0;
        lazy=0;
        zero=false;
    }
};

node segt[26][4*MAXN];

ll a[26];

void lzu(ll main_id , ll id , ll L , ll R)
{
    if (L==R)
    {
        return;
    }

    if (segt[main_id][id].zero)
    {
        segt[main_id][2*id+1].zero=true;
        segt[main_id][2*id+2].zero=true;

        segt[main_id][2*id+1].val=0;
        segt[main_id][2*id+2].val=0;

        segt[main_id][2*id+1].lazy=0;
        segt[main_id][2*id+2].lazy=0;
    }

    ll mid=(L+R)/2;

    segt[main_id][2*id+1].val+=(mid-L+1)*segt[main_id][id].lazy;
    segt[main_id][2*id+2].val+=(R-mid)*segt[main_id][id].lazy;

    segt[main_id][2*id+1].lazy+=segt[main_id][id].lazy;
    segt[main_id][2*id+2].lazy+=segt[main_id][id].lazy;

    segt[main_id][id].lazy=0;
    segt[main_id][id].zero=false;
}

void update(ll main_id , ll id , ll L , ll R , ll l , ll r , ll d)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val+=d*(R-L+1);
        segt[main_id][id].lazy+=d;

        return;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    update(main_id , 2*id+1 , L , mid , l , r , d);
    update(main_id , 2*id+2 , mid+1 , R , l , r , d);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

void zero_update(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val=0;
        segt[main_id][id].lazy=0;
        segt[main_id][id].zero=true;

        return;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    zero_update(main_id , 2*id+1 , L , mid , l , r);
    zero_update(main_id , 2*id+2 , mid+1 , R , l , r);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

ll get_res(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return 0;
    }

    if (L>=l && R<=r)
    {
        return segt[main_id][id].val;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    return get_res(main_id , 2*id+1 , L , mid , l , r)+get_res(main_id , 2*id+2 , mid+1 , R , l , r);
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

	ll n , q;
	fin>>n>>q;

	for(ll i=0;i<n;i++)
    {
        char x;
        fin>>x;

        update(x-'a' , 0 , 0 , n-1 , i , i , 1);
    }

    for(ll i=0;i<q;i++)
    {
        ll l , r , o=-1;
        fin>>l>>r;

        l--;
        r--;

        bool flag=false;

        for(ll j=0;j<26;j++)
        {
            a[j]=get_res(j , 0 , 0 , n-1 , l , r);

            if (a[j]&1)
            {
                if (o==-1)
                {
                    o=j;
                }
                else
                {
                    flag=true;
                }
            }
        }

        if (!flag)
        {
            for(ll j=0;j<26;j++)
            {
                zero_update(j , 0 , 0 , n-1 , l , r);
            }

            if (o!=-1)
            {
                update(o , 0 , 0 , n-1 , l+(r-l+1)/2 , l+(r-l+1)/2 , 1);

                update(o , 0 , 0 , n-1 , l , l+(a[o]/2)-1 , 1);
                l+=a[o]/2;

                update(o , 0 , 0 , n-1 , r-(a[o]/2)+1 , r , 1);
                r-=a[o]/2;
            }

            for(ll j=0;j<26;j++)
            {
                if (a[j]>0 && j!=o)
                {
                    update(j , 0 , 0 , n-1 , l , l+(a[j]/2)-1 , 1);
                    l+=a[j]/2;

                    update(j , 0 , 0 , n-1 , r-(a[j]/2)+1 , r , 1);
                    r-=a[j]/2;
                }

                a[j]=0;
            }
        }
    }

    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<26;j++)
        {
            if (get_res(j , 0 , 0 , n-1 , i , i))
            {
                fout<<char('a'+j);
                break;
            }
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pll pair <ll , ll>

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair

#define X first
#define Y second

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)

#define ll int

const ll MAXN=1e5+10;

struct node
{
    ll val , lazy;

    node()
    {
        val=0;
        lazy=-1;
    }
};

node segt[26][4*MAXN];

ll a[26];

void lzu(ll main_id , ll id , ll L , ll R)
{
    if (L!=R && segt[main_id][id].lazy!=-1)
    {
        ll mid=(L+R)/2;

        segt[main_id][2*id+1].val=(mid-L+1)*segt[main_id][id].lazy;
        segt[main_id][2*id+2].val=(R-mid)*segt[main_id][id].lazy;

        segt[main_id][2*id+1].lazy=segt[main_id][id].lazy;
        segt[main_id][2*id+2].lazy=segt[main_id][id].lazy;
    }

    segt[main_id][id].lazy=-1;
}

void update(ll main_id , ll id , ll L , ll R , ll l , ll r , ll d)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val=d*(R-L+1);
        segt[main_id][id].lazy=d;

        return;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    update(main_id , 2*id+1 , L , mid , l , r , d);
    update(main_id , 2*id+2 , mid+1 , R , l , r , d);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

ll get_res(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return 0;
    }

    if (L>=l && R<=r)
    {
        return segt[main_id][id].val;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    return get_res(main_id , 2*id+1 , L , mid , l , r)+get_res(main_id , 2*id+2 , mid+1 , R , l , r);
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

	ll n , q;
	fin>>n>>q;

	for(ll i=0;i<n;i++)
    {
        char x;
        fin>>x;

        update(x-'a' , 0 , 0 , n-1 , i , i , 1);
    }

    for(ll i=0;i<q;i++)
    {
        ll l , r , o=-1;
        fin>>l>>r;

        l--;
        r--;

        bool flag=false;

        for(ll j=0;j<26;j++)
        {
            a[j]=get_res(j , 0 , 0 , n-1 , l , r);

            if (a[j]&1)
            {
                if (o==-1)
                {
                    o=j;
                }
                else
                {
                    flag=true;
                }
            }
        }

        if (!flag)
        {
            for(ll j=0;j<26;j++)
            {
                update(j , 0 , 0 , n-1 , l , r , 0);
            }

            if (o!=-1)
            {
                update(o , 0 , 0 , n-1 , l+(r-l+1)/2 , l+(r-l+1)/2 , 1);
            }

            for(ll j=0;j<26;j++)
            {
                if (a[j]>0)
                {
                    update(j , 0 , 0 , n-1 , l , l+(a[j]/2)-1 , 1);
                    l+=a[j]/2;

                    update(j , 0 , 0 , n-1 , r-(a[j]/2)+1 , r , 1);
                    r-=a[j]/2;
                }

                a[j]=0;
            }
        }
    }

    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<26;j++)
        {
            if (get_res(j , 0 , 0 , n-1 , i , i))
            {
                fout<<char('a'+j);
                break;
            }
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pll pair <ll , ll>

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair

#define X first
#define Y second

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)

#define ll int

const ll MAXN=1e5+10;

struct node
{
    ll val , lazy;

    node()
    {
        val=0;
        lazy=-1;
    }
};

node segt[26][4*MAXN];

ll a[26];

void lzu(ll main_id , ll id , ll L , ll R)
{
    if (L!=R && segt[main_id][id].lazy!=-1)
    {
        ll mid=(L+R)/2;

        segt[main_id][2*id+1].val=(mid-L+1)*segt[main_id][id].lazy;
        segt[main_id][2*id+2].val=(R-mid)*segt[main_id][id].lazy;

        segt[main_id][2*id+1].lazy=segt[main_id][id].lazy;
        segt[main_id][2*id+2].lazy=segt[main_id][id].lazy;
    }

    segt[main_id][id].lazy=-1;
}

void update(ll main_id , ll id , ll L , ll R , ll l , ll r , ll d)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val=d*(R-L+1);
        segt[main_id][id].lazy=d;

        return;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    update(main_id , 2*id+1 , L , mid , l , r , d);
    update(main_id , 2*id+2 , mid+1 , R , l , r , d);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

ll get_res(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return 0;
    }

    if (L>=l && R<=r)
    {
        return segt[main_id][id].val;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    return get_res(main_id , 2*id+1 , L , mid , l , r)+get_res(main_id , 2*id+2 , mid+1 , R , l , r);
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

	ll n , q;
	fin>>n>>q;

	for(ll i=0;i<n;i++)
    {
        char x;
        fin>>x;

        update(x-'a' , 0 , 0 , n-1 , i , i , 1);
    }

    for(ll i=0;i<q;i++)
    {
        ll l , r , o=-1;
        fin>>l>>r;

        l--;
        r--;

        bool flag=false;

        for(ll j=0;j<26;j++)
        {
            a[j]=get_res(j , 0 , 0 , n-1 , l , r);

            if (a[j]&1)
            {
                if (o==-1)
                {
                    o=j;
                }
                else
                {
                    flag=true;
                }
            }
        }

        if (!flag)
        {
            for(ll j=0;j<26;j++)
            {
                update(j , 0 , 0 , n-1 , l , r , 0);
            }

            if (o!=-1)
            {
                update(o , 0 , 0 , n-1 , l+(r-l+1)/2 , l+(r-l+1)/2 , 1);

                update(o , 0 , 0 , n-1 , l , l+(a[o]/2)-1 , 1);
                l+=a[o]/2;

                update(o , 0 , 0 , n-1 , r-(a[o]/2)+1 , r , 1);
                r-=a[o]/2;
            }

            for(ll j=0;j<26;j++)
            {
                if (a[j]>0 && j!=o)
                {
                    update(j , 0 , 0 , n-1 , l , l+(a[j]/2)-1 , 1);
                    l+=a[j]/2;

                    update(j , 0 , 0 , n-1 , r-(a[j]/2)+1 , r , 1);
                    r-=a[j]/2;
                }

                a[j]=0;
            }
        }
    }

    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<26;j++)
        {
            if (get_res(j , 0 , 0 , n-1 , i , i))
            {
                fout<<char('a'+j);
                break;
            }
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pll pair <ll , ll>

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair

#define X first
#define Y second

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)

#define ll int

const ll MAXN=1e5+10;

struct node
{
    ll val , lazy;

    node()
    {
        val=0;
        lazy=-1;
    }
};

node segt[26][4*MAXN];

ll a[26];

void lzu(ll main_id , ll id , ll L , ll R)
{
    if (L!=R && segt[main_id][id].lazy!=-1)
    {
        ll mid=(L+R)/2;

        segt[main_id][2*id+1].val=(mid-L+1)*segt[main_id][id].lazy;
        segt[main_id][2*id+2].val=(R-mid)*segt[main_id][id].lazy;

        segt[main_id][2*id+1].lazy=segt[main_id][id].lazy;
        segt[main_id][2*id+2].lazy=segt[main_id][id].lazy;
    }

    segt[main_id][id].lazy=-1;
}

void update(ll main_id , ll id , ll L , ll R , ll l , ll r , ll d)
{
    if (L>r || R<l)
    {
        return;
    }

    if (L>=l && R<=r)
    {
        segt[main_id][id].val=d*(R-L+1);
        segt[main_id][id].lazy=d;

        return;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    update(main_id , 2*id+1 , L , mid , l , r , d);
    update(main_id , 2*id+2 , mid+1 , R , l , r , d);

    segt[main_id][id].val=segt[main_id][2*id+1].val+segt[main_id][2*id+2].val;
}

ll get_res(ll main_id , ll id , ll L , ll R , ll l , ll r)
{
    if (L>r || R<l)
    {
        return 0;
    }

    if (L>=l && R<=r)
    {
        return segt[main_id][id].val;
    }

    lzu(main_id , id , L , R);

    ll mid=(L+R)/2;

    return get_res(main_id , 2*id+1 , L , mid , l , r)+get_res(main_id , 2*id+2 , mid+1 , R , l , r);
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

	ll n , q;
	fin>>n>>q;

	for(ll i=0;i<n;i++)
    {
        char x;
        fin>>x;

        update(x-'a' , 0 , 0 , n-1 , i , i , 1);
    }

    for(ll i=0;i<q;i++)
    {
        ll l , r , o=-1;
        fin>>l>>r;

        l--;
        r--;

        bool flag=false;

        for(ll j=0;j<26;j++)
        {
            a[j]=get_res(j , 0 , 0 , n-1 , l , r);

            if (a[j]&1)
            {
                if (o==-1)
                {
                    o=j;
                }
                else
                {
                    flag=true;
                }
            }
        }

        if (!flag)
        {
            for(ll j=0;j<26;j++)
            {
                update(j , 0 , 0 , n-1 , l , r , 0);
            }

            if (o!=-1)
            {
                update(o , 0 , 0 , n-1 , l+(r-l+1)/2 , l+(r-l+1)/2 , 1);
            }

            for(ll j=0;j<26;j++)
            {
                if (a[j]>0 && j!=o)
                {
                    update(j , 0 , 0 , n-1 , l , l+(a[j]/2)-1 , 1);
                    l+=a[j]/2;

                    update(j , 0 , 0 , n-1 , r-(a[j]/2)+1 , r , 1);
                    r-=a[j]/2;
                }

                a[j]=0;
            }
        }
    }

    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<26;j++)
        {
            if (get_res(j , 0 , 0 , n-1 , i , i))
            {
                fout<<char('a'+j);
                break;
            }
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	if(l == r) {
		len[id] = 1;
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	len[id] = r-l+1;
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x]) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		s[p] = 'a'+oi;
		rangeUpdate(oi, p, p, 1);
		p++;
	}
	for(int x = 25; x >= 0; x--) if(cnt[x]) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
		//printf("%s\n", s+1);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	len[id] = r-l+1;
	if(l == r) {
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	if(l == r) {
		len[id] = 1;
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	len[id] = r-l+1;
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x, 1, n, 1);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
		//printf("%s\n", s+1);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	len[id] = r-l+1;
	if(l == r) {
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	rep(x, 26) rep(i, 4*MAXN) lazy[x][i] = -1;

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	len[id] = r-l+1;
	if(l == r) {
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

int mi, ml, mr;
void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	if(id > mi) mi = id, ml = l, mr = r;
	if(l == r) {
		len[id] = 1;
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	len[id] = r-l+1;
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
		//printf("%s\n", s+1);
	}
	if(n == 500) printf("%d %d %d\n", mi, ml, mr);
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	if(l == r) {
		len[id] = 1;
		tree[x][id] = (s[l]-'a' == x) ? 1 : 0;
		return;
	}
	len[id] = r-l+1;
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	memset(lazy, -1, sizeof lazy);

	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
		//printf("%s\n", s+1);
	}
	printf("%s\n", s+1);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 987654321
#define IINF 2987654321987654321
#define MOD 1000000007

const int MAXN = 1e5 + 50;
int tree[26][4*MAXN], lazy[26][4*MAXN], len[4*MAXN], n;
void pushDown(int x, int id) {
	if(lazy[x][id] == 1) {
		tree[x][2*id] = len[2*id];
		tree[x][2*id+1] = len[2*id+1];
		lazy[x][2*id] = lazy[x][2*id+1] = 1;
	} else if(lazy[x][id] == 0) {
		tree[x][2*id] = tree[x][2*id+1] = 0;
		lazy[x][2*id] = lazy[x][2*id+1] = 0;
	}
	lazy[x][id] = -1;
}

void pushUp(int x, int id) {
	tree[x][id] = tree[x][2*id] + tree[x][2*id+1];
}

void buildTree(char *s, int x, int l = 1, int r = n, int id = 1) {
	len[id] = r-l+1;
	if(l == r) {
		tree[x][id] = (s[l]-'a' == x);
		return;
	}
	int mid = (l + r) / 2;
	buildTree(s, x, l, mid, 2*id);
	buildTree(s, x, mid+1, r, 2*id+1);
	pushUp(x, id);
}

void rangeUpdate(int x, int s, int e, int val, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return;
	if(s <= l && r <= e) {
		tree[x][id] = len[id] * val;
		lazy[x][id] = val;
		return;
	}
	int mid = (l + r) / 2;
	pushDown(x, id);
	rangeUpdate(x, s, e, val, l, mid, 2*id);
	rangeUpdate(x, s, e, val, mid+1, r, 2*id+1);
	pushUp(x, id);
}

int rangeSum(int x, int s, int e, int l = 1, int r = n, int id = 1) {
	if(r < s || e < l) return 0;
	if(s <= l && r <= e) return tree[x][id];
	int mid = (l + r) / 2;
	pushDown(x, id);
	int res = rangeSum(x, s, e, l, mid, 2*id) + rangeSum(x, s, e, mid+1, r, 2*id+1);
	pushUp(x, id);
	return res;
}

void query(char *s, int l, int r) {
	vector<int> cnt(26, 0);
	rep(x, 26) cnt[x] = rangeSum(x, l, r);
	int odd = 0, oi = -1;
	rep(x, 26) if(cnt[x]&1) odd++, oi = x;
	if(odd > 1) return;

	rep(x, 26) rangeUpdate(x, l, r, 0);
	int p = l;
	rep(x, 26) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
	if(oi != -1) {
		for(int i = p; i < p + cnt[oi]; i++) s[i] = 'a'+oi;
		rangeUpdate(oi, p, p + cnt[oi] - 1, 1);
		p += cnt[oi];
	}
	for(int x = 25; x >= 0; x--) if(cnt[x] && x != oi) {
		for(int i = p; i < p + cnt[x]/2; i++) s[i] = 'a'+x;
		rangeUpdate(x, p, p + cnt[x]/2 - 1, 1);
		p += cnt[x]/2;
	}
}

char s[MAXN];
int main() {
	memset(lazy, -1, sizeof lazy);
	int q;
	scanf("%d%d%s", &n, &q, s+1);
	rep(x, 26) buildTree(s, x);

	while(q--) {
		int l, r; scanf("%d%d", &l, &r);
		query(s, l, r);
	}
	printf("%s\n", s+1);
}