#include<bits/stdc++.h>
#define int long long
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,b) for(int i=1;i<=b;i++)
using namespace std;
void chmx(int &x,int y){(x<y)&&(x=y);}
void chmn(int &x,int y){(x>y)&&(x=y);}
const int N=2e5+5;
inline int read(){
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f?-x:x;
}
char n,s[N];
int lnk[N];
map<int,int>ch[N];
int len[N],last=1,tot=1;
int tag[N],a[N];
inline void insert(int c){
int p=last,cur=++tot;
last=cur;
len[cur]=len[p]+1;
for(;p&&!ch[p].count(c);p=lnk[p]) ch[p][c]=cur;
if(!p) lnk[cur]=1;
else{
int q=ch[p][c];
if(len[p]+1==len[q]) lnk[cur]=q;
else{
int copy=++tot;
len[copy]=len[p]+1;lnk[copy]=lnk[q];
ch[copy]=ch[q];
lnk[q]=lnk[cur]=copy;
for (;ch[p].count(c)&&p;p=lnk[p]){
if(ch[p][c]==q)ch[p][c]=copy;
else break;
}
}
}
}
int pos[N],rt[N];
int cnt;
struct SegmentTree{
int l,r;
int v;
}tr[N<<3];
inline void modify(int &x,int l,int r,int k){
if(!x) x=++cnt;
tr[x].v++;
if(l==r) return ;
int mid=(l+r)>>1;
if(k<=mid) modify(tr[x].l,l,mid,k);
else modify(tr[x].r,mid+1,r,k);
}
int merge(int x,int y){
if(!x||!y) return x|y;
int nw=++cnt;
tr[nw].v=tr[x].v+tr[y].v;
tr[nw].l=merge(tr[x].l,tr[y].l);
tr[nw].r=merge(tr[x].r,tr[y].r);
return nw;
}
int query(int x,int l,int r,int L,int R){
if(!x) return 0;
if(L<=l&&r<=R) return tr[x].v;
int mid=(l+r)>>1;
int res=0;
if(L<=mid) res+=query(tr[x].l,l,mid,L,R);
if(R>mid) res+=query(tr[x].r,mid+1,r,L,R);
return res;
}
int fa[N][21];
bool ask(int u,int ln,int l,int r){
for(int i=20;i>=0;i--)
if(fa[u][i]&&len[fa[u][i]]>=ln) u=fa[u][i];
return query(rt[u],1,n,l+ln-1,r);
}
inline void work(){
for(int i=1;i<=tot;++i) tag[len[i]]++;
for(int i=1;i<=tot;++i) tag[i]+=tag[i-1];
for(int i=tot;i>=1;--i) a[tag[len[i]]--]=i;
for(int i=tot;i>1;--i){
fa[i][0]=lnk[i];
rt[lnk[a[i]]]=merge(rt[a[i]],rt[lnk[a[i]]]);
}
for(int k=1;k<=20;k++)
for(int i=1;i<=tot;i++)
fa[i][k]=fa[fa[i][k-1]][k-1];
}
signed main(){
n=read();
int Q=read();
scanf("%s",s+1);
reverse(s+1,s+n+1);
for(int i=1;i<=n;i++){
insert(s[i]-'a');
pos[i]=last;
modify(rt[last],1,n,i);
}
work();
while(Q--){
int l1=n-read()+1,r1=n-read()+1,l2=n-read()+1,r2=n-read()+1;
int l=0,r=min(l1-r1+1,l2-r2+1);
int ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(ask(pos[l2],mid,r1,l1)) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%lld\n",ans);
}
return 0;
}