#include <iostream>
#include <string>
using namespace std;
const int MAX_N = 2e5 + 5;
int n, q;
string s;
struct node{
int left, right;
long long size;
};
node merge(node x, node y){
return {x.left, y.right, x.size + y.size};
}
int size_tree;
node tree[4 * MAX_N];
long long the_sum;
int find(long long index){
long long curr_sum = 0;
int tree_node = 1;
while (tree_node < size_tree){
if (curr_sum + tree[2 * tree_node].size + 1 <= index){
curr_sum += tree[2 * tree_node].size;
tree_node = 2 * tree_node + 1;
}
else{
tree_node *= 2;
}
}
the_sum = curr_sum + tree[tree_node].size;
return tree_node;
}
void double_range(long long l, long long r){
int leftmost = find(l);
long long sum1 = the_sum;
int rightmost = find(r);
long long sum2 = the_sum;
if (leftmost == rightmost){
tree[leftmost].size += r - l + 1;
leftmost /= 2;
while (leftmost >= 1){
tree[leftmost] = merge(tree[2 * leftmost], tree[2 * leftmost + 1]);
leftmost /= 2;
}
}
else{
tree[leftmost].size += sum1 - l + 1;
tree[rightmost].size += r - sum2 + 1;
for (int i = leftmost + 1;i <= rightmost - 1;i++){
tree[i].size *= 2;
}
leftmost /= 2, rightmost /= 2;
while (leftmost >= 1){
for (int i = leftmost;i <= rightmost;i++){
tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
}
leftmost /= 2, rightmost /= 2;
}
}
}
int main(){
cin >> n >> q >> s;
size_tree = 1;
while (size_tree < n){
size_tree *= 2;
}
for (int i = 1;i <= size_tree;i++){
tree[size_tree - 1 + i] = {i, i};
if (i <= n){
tree[size_tree - 1 + i].size = 1;
}
}
for (int i = size_tree - 1;i >= 1;i--){
tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
}
for (int i = 1;i <= q;i++){
int type;
cin >> type;
if (type == 1){
long long l, r;
cin >> l >> r;
double_range(l, r);
}
else{
long long index;
cin >> index;
cout << s[find(index) - (size_tree - 1) - 1] << '\n';
}
}
return 0;