#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
#define RG register int
#define LL long long
template<typename elemType>
inline void Read(elemType &T){
elemType X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
T=(w?-X:X);
}
const int INF=2147483647;
const int MAXN=200010;
vector<int> HashData;
int Data[MAXN];
int N,M,ElemNum;
inline void Discretization(){
HashData[0]=-INF;
sort(HashData.begin(),HashData.end());
HashData.erase(unique(HashData.begin(),HashData.end()),HashData.end());
ElemNum=HashData.size()-1;
return;
}
inline int GetPos(int Value){
return lower_bound(HashData.begin(),HashData.end(),Value)-HashData.begin();
}
struct SegmentTree{
struct SegTreeNode{
int Size;
int Lson,Rson;
};
SegTreeNode SegTree[MAXN<<5];
int ROOT[MAXN];
int Index=0;
void Output(int Root,int L,int R){
if(L==R){cout<<SegTree[Root].Size<<" ";return;}
int mid=(L+R)>>1;
Output(SegTree[Root].Lson,L,mid);
Output(SegTree[Root].Rson,mid+1,R);
return;
}
inline void Push_Up(int Root){
int ls=SegTree[Root].Lson;
int rs=SegTree[Root].Rson;
SegTree[Root].Size=SegTree[ls].Size+SegTree[rs].Size;
return;
}
void Build_Empty_SegTree(int &Root,int L,int R){
Root=++Index;
if(L==R){SegTree[Root].Size=0;return;}
int mid=(L+R)>>1;
Build_Empty_SegTree(SegTree[Root].Lson,L,mid);
Build_Empty_SegTree(SegTree[Root].Rson,mid+1,R);
Push_Up(Root);
return;
}
void Insert_Node(int &Pre,int &Cur,int L,int R,int Pos){
Cur=++Index;
SegTree[Cur]=SegTree[Pre];
if(L==R){++SegTree[Cur].Size;return;}
int mid=(L+R)>>1;
if(Pos<=mid) Insert_Node(SegTree[Pre].Lson,SegTree[Cur].Lson,L,mid,Pos);
else Insert_Node(SegTree[Pre].Rson,SegTree[Cur].Rson,mid+1,R,Pos);
Push_Up(Cur);
return;
}
int Get_Kth(int Pre,int Cur,int L,int R,int Kth){
if(L==R) return L;
int mid=(L+R)>>1;
int CLson=SegTree[Cur].Lson;
int PLson=SegTree[Pre].Lson;
int Lsize=SegTree[CLson].Size-SegTree[PLson].Size;
if(Kth<=Lsize) return Get_Kth(SegTree[Pre].Lson,SegTree[Cur].Lson,L,mid,Kth);
return Get_Kth(SegTree[Pre].Rson,SegTree[Cur].Rson,mid+1,R,Kth-Lsize);
}
};
SegmentTree Tree;
int main(){
Read(N);Read(M);
HashData.resize(N+1);
for(RG i=1;i<=N;++i){
Read(Data[i]);
HashData[i]=Data[i];
}
Discretization();
Tree.Build_Empty_SegTree(Tree.ROOT[0],1,ElemNum);
for(RG i=1;i<=N;++i){
int Pos=GetPos(Data[i]);
Tree.Insert_Node(Tree.ROOT[i-1],Tree.ROOT[i],1,ElemNum,Pos);
}
while(M--){
int L,R,Kth,Pos;
Read(L);Read(R);Read(Kth);
Pos=Tree.Get_Kth(Tree.ROOT[L-1],Tree.ROOT[R],1,ElemNum,Kth);
printf("%d\n",HashData[Pos]);
}
return 0;
}