← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

type Node struct {
	cnt  [26]int
	lazy int
}

var tree []Node

func pushDown(node, L, R int) {
	c := tree[node].lazy
	if c != -1 {
		mid := (L + R) / 2
		lc := node * 2
		rc := node*2 + 1

		tree[lc].lazy = c
		tree[lc].cnt = [26]int{}
		tree[lc].cnt[c] = mid - L + 1

		tree[rc].lazy = c
		tree[rc].cnt = [26]int{}
		tree[rc].cnt[c] = R - mid

		tree[node].lazy = -1
	}
}

func pushUp(node int) {
	lc := node * 2
	rc := node*2 + 1
	for i := 0; i < 26; i++ {
		tree[node].cnt[i] = tree[lc].cnt[i] + tree[rc].cnt[i]
	}
}

func build(node, L, R int, s string) {
	tree[node].lazy = -1
	if L == R {
		tree[node].cnt[s[L-1]-'a'] = 1
		return
	}
	mid := (L + R) / 2
	build(node*2, L, mid, s)
	build(node*2+1, mid+1, R, s)
	pushUp(node)
}

func update(node, L, R, qL, qR, c int) {
	if qL <= L && R <= qR {
		tree[node].cnt = [26]int{}
		tree[node].cnt[c] = R - L + 1
		tree[node].lazy = c
		return
	}
	pushDown(node, L, R)
	mid := (L + R) / 2
	if qL <= mid {
		update(node*2, L, mid, qL, qR, c)
	}
	if qR > mid {
		update(node*2+1, mid+1, R, qL, qR, c)
	}
	pushUp(node)
}

func query(node, L, R, qL, qR int, res *[26]int) {
	if qL <= L && R <= qR {
		for i := 0; i < 26; i++ {
			res[i] += tree[node].cnt[i]
		}
		return
	}
	pushDown(node, L, R)
	mid := (L + R) / 2
	if qL <= mid {
		query(node*2, L, mid, qL, qR, res)
	}
	if qR > mid {
		query(node*2+1, mid+1, R, qL, qR, res)
	}
}

func printTree(node, L, R int, out []byte) {
	if L == R {
		for i := 0; i < 26; i++ {
			if tree[node].cnt[i] > 0 {
				out[L-1] = byte('a' + i)
			}
		}
		return
	}
	pushDown(node, L, R)
	mid := (L + R) / 2
	printTree(node*2, L, mid, out)
	printTree(node*2+1, mid+1, R, out)
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
	scanner.Split(bufio.ScanWords)

	scanInt := func() int {
		scanner.Scan()
		res := 0
		for _, b := range scanner.Bytes() {
			res = res*10 + int(b-'0')
		}
		return res
	}

	n := scanInt()
	m := scanInt()

	scanner.Scan()
	s := scanner.Text()

	tree = make([]Node, 4*n+1)
	build(1, 1, n, s)

	for i := 0; i < m; i++ {
		l := scanInt()
		r := scanInt()

		var cnts [26]int
		query(1, 1, n, l, r, &cnts)

		oddCount := 0
		oddChar := -1
		for j := 0; j < 26; j++ {
			if cnts[j]%2 != 0 {
				oddCount++
				oddChar = j
			}
		}

		if oddCount > 1 {
			continue
		}

		leftIdx := l
		rightIdx := r
		for j := 0; j < 26; j++ {
			half := cnts[j] / 2
			if half > 0 {
				update(1, 1, n, leftIdx, leftIdx+half-1, j)
				update(1, 1, n, rightIdx-half+1, rightIdx, j)
				leftIdx += half
				rightIdx -= half
			}
		}
		if oddCount == 1 {
			update(1, 1, n, leftIdx, leftIdx, oddChar)
		}
	}

	out := make([]byte, n)
	printTree(1, 1, n, out)
	fmt.Println(string(out))
}