#include <bits/stdc++.h>
#define ll long long
#define itachi ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define maxn 100005
using namespace std;
const int MAXV = 200005;
const int OFF_NEG = 100002;
const int OFF_POS = 0;
const int MAXNODE = 8000005;
int n, q;
string s;
// ===== PST =====
int Lson[MAXNODE], Rson[MAXNODE];
ll cnt[MAXNODE], sumv[MAXNODE];
int root[4][maxn];
int node = 0;
int new_node(int pre){
int id = ++node;
Lson[id] = Lson[pre];
Rson[id] = Rson[pre];
cnt[id] = cnt[pre];
sumv[id] = sumv[pre];
return id;
}
int build(int l,int r){
int id = ++node;
if(l==r) return id;
int m=(l+r)>>1;
Lson[id]=build(l,m);
Rson[id]=build(m+1,r);
return id;
}
int update(int pre,int l,int r,int pos,ll val){
int id = new_node(pre);
cnt[id]++;
sumv[id]+=val;
if(l==r) return id;
int m=(l+r)>>1;
if(pos<=m) Lson[id]=update(Lson[pre],l,m,pos,val);
else Rson[id]=update(Rson[pre],m+1,r,pos,val);
return id;
}
pair<ll,ll> get(int u,int v,int l,int r,int lim){
if(l>lim) return {0,0};
if(r<=lim) return {cnt[v]-cnt[u], sumv[v]-sumv[u]};
int m=(l+r)>>1;
auto L = get(Lson[u],Lson[v],l,m,lim);
if(lim>m){
auto R = get(Rson[u],Rson[v],m+1,r,lim);
L.first += R.first;
L.second += R.second;
}
return L;
}
// ===== utils =====
ll sum_arith(ll L,ll R){
if(L>R) return 0;
return (L+R)*(R-L+1)/2;
}
// ===== Manacher =====
int d1[maxn], d2[maxn];
void manacher(){
string t="$#";
for(char c: s){
t+=c; t+='#';
}
t+="^";
int m=t.size();
vector<int> P(m);
int C=0,R=0;
for(int i=1;i<m-1;i++){
int mir=2*C-i;
if(i<R) P[i]=min(R-i,P[mir]);
while(t[i+1+P[i]]==t[i-1-P[i]]) P[i]++;
if(i+P[i]>R){
C=i; R=i+P[i];
}
}
for(int i=1;i<=n;i++){
d1[i]=(P[2*i]+1)/2;
if(i<n) d2[i]=P[2*i+1]/2;
}
}
int main(){
itachi
cin>>n>>q>>s;
manacher();
int base = build(1,MAXV);
for(int i=0;i<4;i++) root[i][0]=base;
// ===== build PST =====
for(int i=1;i<=n;i++){
int A1 = d1[i]-i;
int A2 = d1[i]+i;
root[0][i]=update(root[0][i-1],1,MAXV,A1+OFF_NEG,A1);
root[1][i]=update(root[1][i-1],1,MAXV,A2+OFF_POS,A2);
}
for(int i=1;i<n;i++){
int B1 = d2[i]-i;
int B2 = d2[i]+i;
root[2][i]=update(root[2][i-1],1,MAXV,B1+OFF_NEG,B1);
root[3][i]=update(root[3][i-1],1,MAXV,B2+OFF_POS,B2);
}
// ===== queries =====
while(q--){
int l,r;
cin>>l>>r;
ll ans=0;
// ---- odd ----
int mid=(l+r)>>1;
if(l<=mid){
int L=l,R=mid;
int lim=1-l;
auto res=get(root[0][L-1],root[0][R],1,MAXV,lim+OFF_NEG);
ans += res.second + (R-L+1-res.first)*lim + sum_arith(L,R);
}
if(mid+1<=r){
int L=mid+1,R=r;
int lim=r+1;
auto res=get(root[1][L-1],root[1][R],1,MAXV,lim+OFF_POS);
ans += res.second + (R-L+1-res.first)*lim - sum_arith(L,R);
}
// ---- even ----
int mid2=(l+r-1)>>1;
if(l<=mid2){
int L=l,R=mid2;
int lim=1-l;
auto res=get(root[2][L-1],root[2][R],1,MAXV,lim+OFF_NEG);
ans += res.second + (R-L+1-res.first)*lim + sum_arith(L,R);
}
if(mid2+1<=r-1){
int L=mid2+1,R=r-1;
int lim=r;
auto res=get(root[3][L-1],root[3][R],1,MAXV,lim+OFF_POS);
ans += res.second + (R-L+1-res.first)*lim - sum_arith(L,R);
}
cout<<ans<<"\n";
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgbGwgbG9uZyBsb25nCiNkZWZpbmUgaXRhY2hpIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7Y2luLnRpZSgwKTtjb3V0LnRpZSgwKTsKI2RlZmluZSBtYXhuIDEwMDAwNQp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgaW50IE1BWFYgPSAyMDAwMDU7CmNvbnN0IGludCBPRkZfTkVHID0gMTAwMDAyOwpjb25zdCBpbnQgT0ZGX1BPUyA9IDA7CmNvbnN0IGludCBNQVhOT0RFID0gODAwMDAwNTsKCmludCBuLCBxOwpzdHJpbmcgczsKCi8vID09PT09IFBTVCA9PT09PQppbnQgTHNvbltNQVhOT0RFXSwgUnNvbltNQVhOT0RFXTsKbGwgY250W01BWE5PREVdLCBzdW12W01BWE5PREVdOwppbnQgcm9vdFs0XVttYXhuXTsKaW50IG5vZGUgPSAwOwoKaW50IG5ld19ub2RlKGludCBwcmUpewogICAgaW50IGlkID0gKytub2RlOwogICAgTHNvbltpZF0gPSBMc29uW3ByZV07CiAgICBSc29uW2lkXSA9IFJzb25bcHJlXTsKICAgIGNudFtpZF0gPSBjbnRbcHJlXTsKICAgIHN1bXZbaWRdID0gc3VtdltwcmVdOwogICAgcmV0dXJuIGlkOwp9CgppbnQgYnVpbGQoaW50IGwsaW50IHIpewogICAgaW50IGlkID0gKytub2RlOwogICAgaWYobD09cikgcmV0dXJuIGlkOwogICAgaW50IG09KGwrcik+PjE7CiAgICBMc29uW2lkXT1idWlsZChsLG0pOwogICAgUnNvbltpZF09YnVpbGQobSsxLHIpOwogICAgcmV0dXJuIGlkOwp9CgppbnQgdXBkYXRlKGludCBwcmUsaW50IGwsaW50IHIsaW50IHBvcyxsbCB2YWwpewogICAgaW50IGlkID0gbmV3X25vZGUocHJlKTsKICAgIGNudFtpZF0rKzsKICAgIHN1bXZbaWRdKz12YWw7CiAgICBpZihsPT1yKSByZXR1cm4gaWQ7CiAgICBpbnQgbT0obCtyKT4+MTsKICAgIGlmKHBvczw9bSkgTHNvbltpZF09dXBkYXRlKExzb25bcHJlXSxsLG0scG9zLHZhbCk7CiAgICBlbHNlIFJzb25baWRdPXVwZGF0ZShSc29uW3ByZV0sbSsxLHIscG9zLHZhbCk7CiAgICByZXR1cm4gaWQ7Cn0KCnBhaXI8bGwsbGw+IGdldChpbnQgdSxpbnQgdixpbnQgbCxpbnQgcixpbnQgbGltKXsKICAgIGlmKGw+bGltKSByZXR1cm4gezAsMH07CiAgICBpZihyPD1saW0pIHJldHVybiB7Y250W3ZdLWNudFt1XSwgc3Vtdlt2XS1zdW12W3VdfTsKICAgIGludCBtPShsK3IpPj4xOwogICAgYXV0byBMID0gZ2V0KExzb25bdV0sTHNvblt2XSxsLG0sbGltKTsKICAgIGlmKGxpbT5tKXsKICAgICAgICBhdXRvIFIgPSBnZXQoUnNvblt1XSxSc29uW3ZdLG0rMSxyLGxpbSk7CiAgICAgICAgTC5maXJzdCArPSBSLmZpcnN0OwogICAgICAgIEwuc2Vjb25kICs9IFIuc2Vjb25kOwogICAgfQogICAgcmV0dXJuIEw7Cn0KCi8vID09PT09IHV0aWxzID09PT09CmxsIHN1bV9hcml0aChsbCBMLGxsIFIpewogICAgaWYoTD5SKSByZXR1cm4gMDsKICAgIHJldHVybiAoTCtSKSooUi1MKzEpLzI7Cn0KCi8vID09PT09IE1hbmFjaGVyID09PT09CmludCBkMVttYXhuXSwgZDJbbWF4bl07Cgp2b2lkIG1hbmFjaGVyKCl7CiAgICBzdHJpbmcgdD0iJCMiOwogICAgZm9yKGNoYXIgYzogcyl7CiAgICAgICAgdCs9YzsgdCs9JyMnOwogICAgfQogICAgdCs9Il4iOwoKICAgIGludCBtPXQuc2l6ZSgpOwogICAgdmVjdG9yPGludD4gUChtKTsKICAgIGludCBDPTAsUj0wOwoKICAgIGZvcihpbnQgaT0xO2k8bS0xO2krKyl7CiAgICAgICAgaW50IG1pcj0yKkMtaTsKICAgICAgICBpZihpPFIpIFBbaV09bWluKFItaSxQW21pcl0pOwogICAgICAgIHdoaWxlKHRbaSsxK1BbaV1dPT10W2ktMS1QW2ldXSkgUFtpXSsrOwogICAgICAgIGlmKGkrUFtpXT5SKXsKICAgICAgICAgICAgQz1pOyBSPWkrUFtpXTsKICAgICAgICB9CiAgICB9CgogICAgZm9yKGludCBpPTE7aTw9bjtpKyspewogICAgICAgIGQxW2ldPShQWzIqaV0rMSkvMjsKICAgICAgICBpZihpPG4pIGQyW2ldPVBbMippKzFdLzI7CiAgICB9Cn0KCmludCBtYWluKCl7CiAgICBpdGFjaGkKCiAgICBjaW4+Pm4+PnE+PnM7CgogICAgbWFuYWNoZXIoKTsKCiAgICBpbnQgYmFzZSA9IGJ1aWxkKDEsTUFYVik7CiAgICBmb3IoaW50IGk9MDtpPDQ7aSsrKSByb290W2ldWzBdPWJhc2U7CgogICAgLy8gPT09PT0gYnVpbGQgUFNUID09PT09CgogICAgZm9yKGludCBpPTE7aTw9bjtpKyspewogICAgICAgIGludCBBMSA9IGQxW2ldLWk7CiAgICAgICAgaW50IEEyID0gZDFbaV0raTsKCiAgICAgICAgcm9vdFswXVtpXT11cGRhdGUocm9vdFswXVtpLTFdLDEsTUFYVixBMStPRkZfTkVHLEExKTsKICAgICAgICByb290WzFdW2ldPXVwZGF0ZShyb290WzFdW2ktMV0sMSxNQVhWLEEyK09GRl9QT1MsQTIpOwogICAgfQoKICAgIGZvcihpbnQgaT0xO2k8bjtpKyspewogICAgICAgIGludCBCMSA9IGQyW2ldLWk7CiAgICAgICAgaW50IEIyID0gZDJbaV0raTsKCiAgICAgICAgcm9vdFsyXVtpXT11cGRhdGUocm9vdFsyXVtpLTFdLDEsTUFYVixCMStPRkZfTkVHLEIxKTsKICAgICAgICByb290WzNdW2ldPXVwZGF0ZShyb290WzNdW2ktMV0sMSxNQVhWLEIyK09GRl9QT1MsQjIpOwogICAgfQoKICAgIC8vID09PT09IHF1ZXJpZXMgPT09PT0KICAgIHdoaWxlKHEtLSl7CiAgICAgICAgaW50IGwscjsKICAgICAgICBjaW4+Pmw+PnI7CiAgICAgICAgbGwgYW5zPTA7CgogICAgICAgIC8vIC0tLS0gb2RkIC0tLS0KICAgICAgICBpbnQgbWlkPShsK3IpPj4xOwoKICAgICAgICBpZihsPD1taWQpewogICAgICAgICAgICBpbnQgTD1sLFI9bWlkOwogICAgICAgICAgICBpbnQgbGltPTEtbDsKICAgICAgICAgICAgYXV0byByZXM9Z2V0KHJvb3RbMF1bTC0xXSxyb290WzBdW1JdLDEsTUFYVixsaW0rT0ZGX05FRyk7CiAgICAgICAgICAgIGFucyArPSByZXMuc2Vjb25kICsgKFItTCsxLXJlcy5maXJzdCkqbGltICsgc3VtX2FyaXRoKEwsUik7CiAgICAgICAgfQoKICAgICAgICBpZihtaWQrMTw9cil7CiAgICAgICAgICAgIGludCBMPW1pZCsxLFI9cjsKICAgICAgICAgICAgaW50IGxpbT1yKzE7CiAgICAgICAgICAgIGF1dG8gcmVzPWdldChyb290WzFdW0wtMV0scm9vdFsxXVtSXSwxLE1BWFYsbGltK09GRl9QT1MpOwogICAgICAgICAgICBhbnMgKz0gcmVzLnNlY29uZCArIChSLUwrMS1yZXMuZmlyc3QpKmxpbSAtIHN1bV9hcml0aChMLFIpOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLSBldmVuIC0tLS0KICAgICAgICBpbnQgbWlkMj0obCtyLTEpPj4xOwoKICAgICAgICBpZihsPD1taWQyKXsKICAgICAgICAgICAgaW50IEw9bCxSPW1pZDI7CiAgICAgICAgICAgIGludCBsaW09MS1sOwogICAgICAgICAgICBhdXRvIHJlcz1nZXQocm9vdFsyXVtMLTFdLHJvb3RbMl1bUl0sMSxNQVhWLGxpbStPRkZfTkVHKTsKICAgICAgICAgICAgYW5zICs9IHJlcy5zZWNvbmQgKyAoUi1MKzEtcmVzLmZpcnN0KSpsaW0gKyBzdW1fYXJpdGgoTCxSKTsKICAgICAgICB9CgogICAgICAgIGlmKG1pZDIrMTw9ci0xKXsKICAgICAgICAgICAgaW50IEw9bWlkMisxLFI9ci0xOwogICAgICAgICAgICBpbnQgbGltPXI7CiAgICAgICAgICAgIGF1dG8gcmVzPWdldChyb290WzNdW0wtMV0scm9vdFszXVtSXSwxLE1BWFYsbGltK09GRl9QT1MpOwogICAgICAgICAgICBhbnMgKz0gcmVzLnNlY29uZCArIChSLUwrMS1yZXMuZmlyc3QpKmxpbSAtIHN1bV9hcml0aChMLFIpOwogICAgICAgIH0KCiAgICAgICAgY291dDw8YW5zPDwiXG4iOwogICAgfQp9