#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 100005#define maxm 50005int ls[maxn],rs[maxn],s[maxn],value[maxn];int node,root;void init(){ node=root=s[0]=0;}void Right_Rotate(int &t){ int k=ls[t]; ls[t]=rs[k]; rs[k]=t; s[k]=s[t]; s[t]=s[ls[t]]+s[rs[t]]+1; t=k;}void Left_Rotate(int &t){ int k=rs[t]; rs[t]=ls[k]; ls[k]=t; s[k]=s[t]; s[t]=s[ls[t]]+s[rs[t]]+1; t=k;}void Maintain(int &t,bool flag){ if(flag) if(s[rs[rs[t]]]>s[ls[t]]) Left_Rotate(t); else if(s[ls[rs[t]]]>s[ls[t]]) Right_Rotate(rs[t]),Left_Rotate(t); else return ; else if(s[ls[ls[t]]]>s[rs[t]]) Right_Rotate(t); else if(s[rs[ls[t]]]>s[rs[t]]) Left_Rotate(ls[t]),Right_Rotate(t); else return ; Maintain(ls[t],0); Maintain(rs[t],1); Maintain(t,0); Maintain(t,1);}void Insert(int &t,int val) //将键值为v的结点插入到根为t的树中{ if(t) { ++s[t]; if(val<value[t]) Insert(ls[t],val); else Insert(rs[t],val); Maintain(t,val>=value[t]); } else { s[t=++node]=1; value[t]=val; ls[t]=rs[t]=0; }}int Delete(int &t,int val) //在根为t的树中删除键值为v的结点{ --s[t]; if(val==value[t]||val<value[t]&&!ls[t]||val>value[t]&&!rs[t]) { int tmp=value[t]; if(!ls[t]||!rs[t]) t=ls[t]+rs[t]; else value[t]=Delete(ls[t],value[t]+1); return tmp; } else if(val<value[t]) return Delete(ls[t],val); else return Delete(rs[t],val);}int Pred(int t,int val) //返回根为t的树中比v小的最大的键值{ if(!t) return val; if(val<=value[t]) return Pred(ls[t],val); else { int tmp=Pred(rs[t],val); return tmp==val?value[t]:tmp; }}int Succ(int t,int val) //返回根为t的树中比v大的最小的键值{ if(!t) return val; if(val>=value[t]) return Succ(rs[t],val); else { int tmp=Succ(ls[t],val); return tmp==val?value[t]:tmp; }}int Find(int t,int val) //在根为t的树中查找键值为v的结点{ while(t&&val!=value[t]) t=val<value[t]?Find(ls[t],val):Find(rs[t],val); return t;}int Rank(int t,int val) //返回根为t的树中键值v的排名。也就是树中键值比v小的结点数+1{ if(!t) return 1; if(val<=value[t]) return Rank(ls[t],val); else return s[ls[t]]+1+Rank(rs[t],val);}int Select(int t,int k) //返回根为t的树中排名为k的结点。//同时该操作能够实现Get-min,Get-max,因为Get-min等于Select(t,1),Get-max等于Select(t,s[t]){ if(k==s[ls[t]]+1) return value[t]; if(k<=s[ls[t]]) return Select(ls[t],k); else return Select(rs[t],k-1-s[ls[t]]);}void Debug(int t){ if(!t) { puts("empty!"); return ; } if(ls[t]) Debug(ls[t]); printf("%d ",value[t]); if(rs[t]) Debug(rs[t]);}struct qnode{ int l,r,k,id; bool operator < (const qnode &tmp) const { return l<tmp.l; }} q[maxm];int a[maxn],ans[maxm],mp[maxn];int main(){ int n,m; scanf("%d%d",&n,&m); init(); for(int i=1; i<=n; i++) scanf("%d",a+i); for(int i=1; i<=m; i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k); q[i].id=i; } sort(q+1,q+1+m); q[0].l=0,q[0].r=0; for(int i=1; i<=m; i++) { for(int j=q[i-1].l; j<=q[i-1].r&&j<q[i].l; j++) if(j==0) continue; else Delete(root,a[j]); //Debug(root); for(int j=q[i-1].r>=q[i].l?q[i-1].r+1:q[i].l; j<=q[i].r; j++) { Insert(root,a[j]); //Debug(root); } ans[q[i].id]=Select(root,q[i].k); } for(int i=1; i<=m; i++) printf("%d\n",ans[i]); return 0;}