import java.util.*;
import java.util.stream.Collectors;
public class Main {
static final int N = 200010;
static Node[] tree = new Node[40 * N];
static int[] root = new int[N], a = new int[N];
static int n, m, idx = 0;
static List<Integer> sorted = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
sorted.add(a[i]);
}
discretize(sorted);
root[0] = build(1, sorted.size());//创建空树
for (int i = 1; i <= n; i++) {
int x = find(a[i]);//查找
root[i] = update(root[i - 1], 1, sorted.size(), x, 1);//在该位置加1表示出现多1次
}
for (int i = 0; i < m; i++) {
int l = sc.nextInt();
int r = sc.nextInt();
int k = sc.nextInt();
/*
查找[l, r]第k小的数
树种存储的是[1, i]的前缀数字出现情况
所以需要查询[l - 1, r]的前缀数字出现情况
上面进行离散化保证了数字的大小关系
所以可以通过查询[1, r]的前缀数字出现情况 - [1, l - 1]的前缀数字出现情况
得到[l, r]的前缀数字出现情况
然后通过二分查找找到第k小的数字
*/
System.out.println(getIndex(query(root[l - 1], root[r], 1, sorted.size(), k)));
}
}
static int find(int x) {
return Collections.binarySearch(sorted, x) + 1;
}
static int getIndex(int x) {
return sorted.get(x - 1);
}
static void discretize(List<Integer> list) {
List<Integer> unique = list.stream().sorted().distinct().collect(Collectors.toList());
list.clear();
list.addAll(unique);
}
static int build(int l, int r) {
int p = ++idx;
tree[p] = new Node();
if (l == r) return p;
int mid = (l + r) >> 1;
tree[p].ls = build(l, mid);
tree[p].rs = build(mid + 1, r);
return p;
}
static int update(int pre, int l, int r, int x, int v) {
int p = ++idx;
if (tree[p] == null) {
tree[p] = new Node();
tree[p].cnt = tree[pre].cnt;
}
if (l == r) {
tree[p].cnt += v;
return p;
}
int mid = (l + r) >> 1;
if (x <= mid) {
tree[p].rs = tree[pre].rs;
tree[p].ls = update(tree[pre].ls, l, mid, x, v);
} else {
tree[p].ls = tree[pre].ls;
tree[p].rs = update(tree[pre].rs, mid + 1, r, x, v);
}
pushup(p);
return p;
}
static void pushup(int p) {
tree[p].cnt = tree[tree[p].ls].cnt + tree[tree[p].rs].cnt;
}
static int query(int pre, int now, int l, int r, int k) {
if (l == r) return l;
int mid = (l + r) >> 1;
int leftCnt = tree[tree[now].ls].cnt - tree[tree[pre].ls].cnt;
int res = 0;
if (k <= leftCnt) {
res = query(tree[pre].ls, tree[now].ls, l, mid, k);
} else {
res = query(tree[pre].rs, tree[now].rs, mid + 1, r, k - leftCnt);
}
return res;
}
}
class Node {
int cnt;//该节点的数字出现次数
int ls, rs;//左右子树的节点编号
}