#include
using namespace std;
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,q;
char t[N];
int sa[N],rk[N],od[N],cnt[N],id[N],px[N];
ll h[N];
int root[N];
ll f[N][26];
ll lg[N],idx;
struct node{
int l,r;
int cnt;
}tr[40*N];
bool cmp(int x, int y, int w){
return od[x]==od[y]&&od[x+w]==od[y+w];
}
void build(int &rt,int l,int r){
rt=++idx;
tr[rt]={l,r,0};
if(l==r)
return;
int mid=l+r>>1;
build(tr[rt].l,l,mid);
build(tr[rt].r,mid+1,r);
}
void da(int n,int m){
int i;
memset(cnt,0,sizeof cnt);
for(i=1;i<=n;i++) cnt[rk[i]=t[i]]++;
for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;
int p;
for(int w=1;w1,m=p){
p=0;
for(i=n;i>n-w;i--)
id[++p]=i;
for(i=1;i<=n;i++)
if(sa[i]>w)
id[++p]=sa[i]-w;
memset(cnt,0,sizeof cnt);
for(i=1;i<=n;i++) cnt[px[i]=rk[id[i]]]++;
for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(i=n;i>=1;i--) sa[cnt[px[i]]--]=id[i];
for(i=0;i<=n;i++) od[i]=rk[i];
for(p=0,i=1;i<=n;i++){
rk[sa[i]]=cmp(sa[i-1],sa[i],w)?p:++p;
}
}
}
void st(int n){
int i,j;
for(i=1;i<=n;i++)
f[i][0]=h[i];
lg[1]=0;
for(i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(j=1;j<=lg[n];j++){
for(i=1;i+(1<1<=n;i++){
f[i][j]=min(f[i][j-1],f[i+(1<1)][j-1]);
}
}
}
int query(int l,int r){
if(l>r)
swap(l,r);
l++;
int len=lg[r-l+1];
return min(f[l][len],f[r-(1<1][len]);
}
void get_height(int n){
int i;
for(i=1;i<=n;i++){
if(rk[i]==1)
continue;
int a=max(h[rk[i-1]]-1,1ll*0);
while(i+a<=n&&t[i+a]==t[sa[rk[i]-1]+a])
a++;
h[rk[i]]=a;
}
st(n);
}
int getL(int l,int r,int len,int x){
while(l<r){
int mid=l+r>>1;
if(query(mid,x)>=len){
r=mid;
}
else{
l=mid+1;
}
}
return l;
}
int getR(int l,int r,int len,int x){
while(l<r){
int mid=l+r+1>>1;
if(query(mid,x)>=len)
l=mid;
else
r=mid-1;
}
return l;
}
int getans(int p,int q,int l,int r,int k){
if(l==r)
return l;
int cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;
int mid=l+r>>1;
if(k<=cnt)
return getans(tr[p].l,tr[q].l,l,mid,k);
else
return getans(tr[p].r,tr[q].r,mid+1,r,k-cnt);
}
int solve(int l,int r,int k){
int len=r-l+1;
int L=getL(1,rk[l],len,rk[l]);
int R=getR(rk[l],n,len,rk[l]);
if(k>R-L+1)
return -1;
return getans(root[L-1],root[R],1,n,k);
}
void add(int &rt,int l,int r,int p,int pos,int k){
rt=++idx;tr[rt]=tr[p];
if(l==r){
tr[rt].cnt+=k;
return ;
}
int mid=l+r>>1;
if(pos<=mid) add(tr[rt].l,l,mid,tr[p].l,pos,k);
else add(tr[rt].r,mid+1,r,tr[p].r,pos,k);
tr[rt].cnt=tr[tr[rt].l].cnt+tr[tr[rt].r].cnt;
}
int main(){
//ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
scanf("%d%d",&n,&q);
scanf("%s",t+1);
int lent=strlen(t+1);
da(lent,150);
get_height(lent);
idx=0;
build(root[0],1,n);
for(int i=1;i<=n;i++){
int pos=sa[i];
add(root[i],1,n,root[i-1],pos,1);
}
while(q--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
cout<endl;
}
}
}