Link to this code: https://cses.fi/paste/cbc9634c483e5b6799cb1a/
#include <bits/stdc++.h>
using namespace std;

#define rep(i, from, to) for (int i = from; i < (to); ++i)

// begin KACTL


struct Node {
	Node* l = 0, * r = 0;
	int val, y, c = 1;
	Node(int val) : val(val), y(rand()) {}
	void recalc();
};

int cnt(Node * n) { return n ? n->c : 0; }
void Node::recalc() { c = cnt(l) + cnt(r) + 1; }

template<class F> void each(Node * n, F f) {
	if (n) { each(n->l, f); f(n->val); each(n->r, f); }
}

pair<Node*, Node*> split(Node * n, int k) {
	if (!n) return {};
	if (cnt(n->l) >= k) { // "n->val >= k" for lower_bound(k)
		auto pa = split(n->l, k);
		n->l = pa.second;
		n->recalc();
		return { pa.first, n };
	}
	else {
		auto pa = split(n->r, k - cnt(n->l) - 1); // and just "k"
		n->r = pa.first;
		n->recalc();
		return { n, pa.second };
	}
}

Node* merge(Node * l, Node * r) {
	if (!l) return r;
	if (!r) return l;
	if (l->y > r->y) {
		l->r = merge(l->r, r);
		l->recalc();
		return l;
	}
	else {
		r->l = merge(l, r->l);
		r->recalc();
		return r;
	}
}

Node* ins(Node * t, Node * n, int pos) {
	auto pa = split(t, pos);
	return merge(merge(pa.first, n), pa.second);
}

// Example application: move the range [l, r) to index k
void move(Node * &t, int l, int r, int k) {
	Node* a, * b, * c;
	tie(a, b) = split(t, l); tie(b, c) = split(b, r - l);
	if (k <= l) t = merge(ins(a, b, k), c);
	else t = merge(a, ins(c, b, k - r));
}
//end KACTL

int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int n, q;
	cin >> n >> q;
	string s;
	cin >> s;
	Node* root = 0;
	for (int i = 0; i < n; i++)
	{
		Node* e = new Node(s[i]);
		root = merge(root, e);
	}
	for (int i = 0; i < q; i++)
	{
		int l, r;
		cin >> l >> r;
		l--; r--;
		move(root, l, r + 1, n);
	}
	each(root, [](int x)
		{
			cout << (char)x;
		});

	return 0;
}