#include <algorithm>
#include <bits/stdc++.h>
#include <vector>
using std::cin;
using std::cout;
#define endl '\n'
// using std::endl; // I won't use you forever!
typedef const int& cint;
typedef long long LL;
typedef const LL& cll;
cint maxn = 1e5 + 10;
int n, m, k;
#define now t[id]
#define lch t[now.lid]
#define rch t[now.rid]
#define pre t[pid]
#define m ((l + r) >> 1)
struct node {
int cnt;
int lid, rid;
} t[maxn << 5];
int tot, rt[maxn]; // 内存池顶、树的切片(根位置)
// int build(int id, int l, int r); // 完全没必要 空树就空的
void pushup(int id) { now.cnt = lch.cnt + rch.cnt; }
// 权值线段树会直接搜到底 建一个链即可
int mod(int id, int l, int r, int q, int cnt, int pid) {
if (id == 0) id = ++tot;
if (l == r) {
now.cnt = pre.cnt + cnt;
return id;
}
// now.lid = pre.lid, now.rid = pre.rid;
// 先同步过来(很危险啊 别这样写 会让下一个mod不新建节点)
int mid = m;
if (q <= mid)
now.lid = mod(now.lid, l, mid, q, cnt, pre.lid), now.rid = pre.rid;
else now.rid = mod(now.rid, mid + 1, r, q, cnt, pre.rid), now.lid = pre.lid;
pushup(id);
return id;
}
int kmin(int id, int l, int r, int k, int pid) {
if (l == r) return l;
int mid = m;
int lcnt = t[now.lid].cnt - t[pre.lid].cnt; // 第k小 求左侧
if (k <= lcnt) return kmin(now.lid, l, mid, k, pre.lid);
else return kmin(now.rid, mid + 1, r, k - lcnt, pre.rid);
}
#undef m
std::vector<int> a;
int main() {
std::ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
a.push_back(x);
}
std::vector<int> fx(a);
std::sort(fx.begin(), fx.end());
int N =
std::unique(fx.begin(), fx.end()) - fx.begin(); // 总共(不重)的个数
for (int i = 0; i < n; i++) {
int pos = std::lower_bound(fx.begin(), fx.end(), a[i]) - fx.begin();
rt[i + 1] = mod(rt[i + 1], 1, N, pos + 1, 1, rt[i]);
}
while (m--) {
int l, r, k;
cin >> l >> r >> k;
cout << fx[kmin(rt[r], 1, N, k, rt[l - 1]) - 1] << endl;
}
return 0;
}
70pts,WA了中间3,4,5