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))
}