//如果a[i]-1 和 a[i] + 1都没有维护过的话,那么就是多一个新串
//如果 a[i] - 1和a[i] + 1 有一个被维护过了,那么接上就好
//如果 a[i] -1 和a[i] + 1 都被维护过了,那么把两个合成一个,就少一个串
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
struct node{
int L,R,id;
} ask[maxn];
int ans[maxn];
int a[maxn],num[maxn];//从1开始计数
int n,m,siz,temp;//n个数,m个询问,块的大小
bool cmp(node a,node b) {//分块排序
if(a.L/siz!=b.L/siz)
return a.L/siz<b.L/siz;
else return a.R<b.R;
}
void sub(int pos) {
int x=a[pos];
num[x]=0;
if(num[x-1]==0&&num[x+1]==0)
temp--;
if(num[x-1]==1&&num[x+1]==1)
temp++;
}
void add(int pos) {
int x=a[pos];
num[x]=1;
if(num[x-1]==0&&num[x+1]==0)
temp++;
if(num[x-1]==1&&num[x+1]==1)
temp--;
}
void solve() {
temp=0;
memset(num,0,sizeof num);
int L=1,R=0;
for(int i=1; i<=m; i++) {
while(R<ask[i].R) {
R++;
add(R);
}
while(R>ask[i].R) {
sub(R);
R--;
}
while(L<ask[i].L) {
sub(L);
L++;
}
while(L>ask[i].L) {
L--;
add(L);
}
ans[ask[i].id]=temp;
}
}
int main() {
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=1; i<=m; i++) {
ask[i].id=i;
scanf("%d%d",&ask[i].L,&ask[i].R);
}
siz=sqrt(n);
sort(ask+1,ask+m+1,cmp);
solve();
for(int i=1; i<=m; i++)
printf("%d
",ans[i]);
}
return 0;
}