#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200100;
struct Q
{
int l,r,id;
bool operator < (const Q& rhs)const
{
return r<rhs.r;
}
}q[maxn];
int isp[maxn],p[maxn],w[maxn],tp[maxn];
int l[maxn],r[maxn],sum[maxn],ans[maxn];
vector<int> hav[maxn],vt[maxn];
int n,m;
void getp()
{
int cnt,i,j;
cnt=0;
memset(isp,true,sizeof(isp));
isp[0]=isp[1]=false;
for(i=2;i<maxn;i++)
{
if(isp[i])
{
p[cnt++]=i;
for(j=i;j<maxn;j+=i)
isp[j]=false;
}
}
}
void gethav()
{
int i,j,ti;
for(i=2;i<maxn;i++)
{
ti=i;
for(j=0;p[j]*p[j]<=ti;j++)
{
if(ti%p[j]==0)
{
hav[i].push_back(p[j]);
while(ti%p[j]==0)ti/=p[j];
}
}
if(ti>1)hav[i].push_back(ti);
}
}
int lowbit(int i)
{
return i&(-i);
}
void add(int pos,int key)
{
int i,j;
if(!pos)return;
for(i=pos;i<=n;i+=lowbit(i))
sum[i]+=key;
}
int getsum(int L,int R)
{
int i,j,res;
res=0;
for(i=R;i>0;i-=lowbit(i))
res+=sum[i];
for(i=L-1;i>0;i-=lowbit(i))
res-=sum[i];
return res;
}
void init()
{
int i,j,v;
for(i=1;i<=n;i++)
{
scanf("%d",&w[i]);
}
memset(tp,-1,sizeof(tp));
for(i=1;i<=n;i++)
{
l[i]=1;
for(j=0;j<hav[w[i]].size();j++)
{
v=hav[w[i]][j];
if(tp[v]!=-1)
l[i]=max(l[i],tp[v]+1);
tp[v]=i;
}
}
memset(tp,-1,sizeof(tp));
for(i=n;i>=1;i--)
{
r[i]=n;
for(j=0;j<hav[w[i]].size();j++)
{
v=hav[w[i]][j];
if(tp[v]!=-1)
r[i]=min(r[i],tp[v]-1);
tp[v]=i;
}
}
}
void slove()
{
int i,j,ri,id;
for(i=0;i<m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q,q+m);
for(i=0;i<maxn;i++)
{
sum[i]=0;
vt[i].clear();
}
for(i=1;i<=n;i++)
{
vt[r[i]+1].push_back(i);
}
i=0;
for(ri=1;ri<=n;ri++)
{//加入ri点
add(ri,1);
add(l[ri]-1,-1);
for(j=0;j<vt[ri].size();j++)
{//把不能到达ri的点删掉
id=vt[ri][j];
add(id,-1);
add(l[id]-1,1);
}
while(i<m&&q[i].r==ri)
{//如果访问的区间刚好是ri,才去计算这个访问的答案,这样可以避免无端减少或加上影响答案的数
//如果边处理区间边加点有麻烦,就试着换个思路,边加点边处理区间咯
ans[q[i].id]=getsum(q[i].l,q[i].r);//以上注释该是离线处理的精髓吧=.=
i++;
}
}
for(i=0;i<m;i++)
printf("%d\n",ans[i]);
}
int main()
{
getp();
gethav();
while(scanf("%d%d",&n,&m),n||m)
{
init();
slove();
}
}