#include <iostream>
#include <cstring>
#include <algorithm>
#include<stdio.h>
using namespace std;
const int N=2e5+10;
//用线段树维护每个区间的最大值和最小值以及区间和
struct node
{
int l,r,li,ri,sum;
}tr[N*4];
char ai[N];
int bi[N];
int n,m;
void pushup(int u)
{
tr[u].sum=tr[u*2].sum+tr[u*2+1].sum;
tr[u].li=min(tr[u*2].li,tr[2*u].sum+tr[u*2+1].li);
tr[u].ri=max(tr[u*2].ri,tr[u*2+1].ri+tr[u*2].sum);
tr[u].ri=max(tr[u].ri,0);
tr[u].li=min(tr[u].li,0);
}
void build(int u,int l,int r)
{
tr[u]={l,r,0,0,0};
if(l==r)
{
tr[u]={l,r,0,0,0};
if(bi[l]==1)tr[u]={l,r,0,1,1};
else tr[u]={l,r,-1,0,-1};
tr[u].li=min(tr[u].li,0);
tr[u].ri=max(tr[u].ri,0);
return;
}
int mid=l+r>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
pushup(u);
return;
}
node query(int u,int l,int r)
{
if(tr[u].r<=r&&tr[u].l>=l)
{
return tr[u];
}
int mid=tr[u].l+tr[u].r>>1;
node a={0,0,0,0,0},b={0,0,0,0,0};
if(l<=mid)a=query(u*2,l,r);
if(r>mid)b=query(u*2+1,l,r);
node c;
if(l<=mid&&r>mid)
{
c.li=min(a.li,b.li+a.sum);
c.ri=max(a.ri,a.sum+b.ri);
c.li=min(c.li,0);
c.ri=max(c.ri,0);
c.sum=a.sum+b.sum;
return c;
}
else if(l<=mid)return a;
else return b;
}
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n>>m;
cin >> ai+1;
for(int i=1;i<=ai[i];i++)
{
if(ai[i]=='+')bi[i]=1;
else bi[i]=-1;
}
build(1,1,n);
//cout << tr[1].li<<" "<<tr[1].ri<<" "<<tr[1].sum<<endl;
while (m -- )//求出1---》l-1区间的信息,r+1---n区间的信息把这两个区间信息合并来计算答案
{
int l,r;
cin >> l>>r;
int li,ri;
if(l-1>=1&&r+1<=n)
{
node dd=query(1,1,l-1);
node ff=query(1,r+1,n);
li=min(dd.li,dd.sum+ff.li);
ri=max(dd.ri,dd.sum+ff.ri);
}
else if(l-1>=1)
{
node dd=query(1,1,l-1);
//cout << dd.li<<" "<<dd.ri<<" "<<dd.sum<<endl;
li=dd.li,ri=dd.ri;
}
else if(r+1<=n)
{
node ff=query(1,r+1,n);
li=ff.li;
ri=ff.ri;
}
else
{
li=0,ri=0;
}
if(li==0||ri==0) cout << ri-li+1<<endl;
else cout << ri-li+1<<endl;
}
}
return 0;
}