#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
const int MAXN = 1e5+10;
int a[MAXN],sorted[MAXN];
struct Trie{
int num[20][MAXN];//进入左区间的数量
int val[20][MAXN];//记录第i层元素序列
int lsum[20][MAXN];
int isum;
void init(int n){
for(int i = 1; i <= n; ++i){
val[0][i] = a[i];
}
for(int i = 0; i < 20; ++i){
lsum[i][0] = 0,num[i][0] = 0,val[i][0] = 0;
}
}
void build(int l,int r,int deep){
if(l == r)return ;
int mid = (l+r)>>1;
int lnum = mid-l+1;
for(int i = l; i <= mid; ++i){
if(sorted[i] < sorted[mid]){
lnum--;
}
}
int lp = l,rp = mid+1;
for(int i = l; i <= r; ++i){
lsum[deep][i] = lsum[deep][i-1];
num[deep][i] = num[deep][i-1];
if((val[deep][i] < sorted[mid])||(val[deep][i]==sorted[mid]&&lnum)){
val[deep+1][lp++] = val[deep][i];
lsum[deep][i] += val[deep][i];
num[deep][i]++;
if(val[deep][i]==sorted[mid]) lnum--;
}
else{
val[deep+1][rp++] = val[deep][i];
}
}
build(l,mid,deep+1);
build(mid+1,r,deep+1);
}
int query(int deep,int l,int r,int lp,int rp,int k){
int s,ss;
if(l == r) return val[deep][l];
s = num[deep][lp-1]-num[deep][l-1];
ss = num[deep][rp]-num[deep][lp-1];
int mid = (l+r)>>1;
if(k <= ss){
// 左区间
return query(deep+1,l,mid,l+s,l+s+ss-1,k);
}
else{
//右区间
//mid+1 + (lp-1-l+1-s);
//mid+1 + (lp-1-l+1-s) + (rp-lp+1-ss) - 1
isum += (lsum[deep][rp]-lsum[deep][lp-1]);
return query(deep+1,mid+1,r,mid-l+1-s+lp,mid-l+1+rp-s-ss,k-ss);
}
}
};
Trie tree;
int main(){
int i, j, k;
int n,m;
while(~scanf("%d%d", &n, &m)){
for (i = 1; i <= n; i++){
scanf("%d", &a[i]);
sorted[i] = a[i];
}
tree.init(n);
sort(sorted + 1, sorted + 1 + n);
tree.build(1,n,0);
while(m--){
tree.isum = 0;
scanf("%d%d%d",&i,&j,&k);// i,j分别为区间起始点,k为该区间第k小的数。
int res = tree.query(0, 1, n, i, j, k);
printf("%d,%d\n",res,tree.isum);
}
}
return 0;
}