#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100100;
const int INF=1e9+10;
int n,m;
int L,R,k;
int a[maxn],b[maxn],bn;
struct SegTree
{
int l,r;
int ls,rs;
int sum;
void debug()
{
printf("l=%2d r=%2d ls=%2d rs=%2d sum=%2d
",l,r,ls,rs,sum);
}
};SegTree T[maxn*64];
int root[maxn],tot;
void push_up(int rt)
{
T[rt].sum=T[T[rt].ls].sum+T[T[rt].rs].sum;
}
int build(int l,int r)
{
int k=++tot;
T[k].l=l;T[k].r=r;
T[k].ls=-1;T[k].rs=-1;
T[k].sum=0;
if(l==r) return k;
int m=(l+r)>>1;
T[k].ls=build(l,m);
T[k].rs=build(m+1,r);
push_up(k);
return k;
}
int update(int rt,int p,int c)
{
int k=++tot;
T[k]=T[rt];
if(T[rt].l==T[rt].r){
T[k].sum+=c;
return k;
}
int m=(T[rt].l+T[rt].r)>>1;
if(p<=m) T[k].ls=update(T[rt].ls,p,c);
else T[k].rs=update(T[rt].rs,p,c);
push_up(k);
return k;
}
int query(int s,int t,int k)
{
if(T[s].l==T[s].r) return T[s].l;
int cnt=T[T[s].ls].sum-T[T[t].ls].sum;
if(k<=cnt) return query(T[s].ls,T[t].ls,k);
else return query(T[s].rs,T[t].rs,k-cnt);
}
int main()
{
freopen("in.txt","r",stdin);
while(cin>>n>>m){
REP(i,1,n) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
bn=unique(b+1,b+n+1)-(b+1);
REP(i,1,n) a[i]=lower_bound(b+1,b+bn+1,a[i])-b;
tot=0;
root[0]=build(1,bn);
REP(i,1,n){
root[i]=update(root[i-1],a[i],1);
}
while(m--){
scanf("%d%d%d",&L,&R,&k);
int kth=query(root[R],root[L-1],k);
printf("%d
",b[kth]);
}
}
return 0;
}