推一推
答案是
∏T(∏d|Tfμ(Td)d)⌊nT⌋⌊mT⌋
O(nlnn) 筛一下括号里的东西,分块搞
include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1000010,P=1e9+7;
int t,n,m,mu[N],p[N],g[N],f[N],h[N],invh[N];
inline int Pow(int x,ll y){
int ret=1;
for(;y;y>>=1,x=1LL*x*x%P) if(y&1) ret=1LL*ret*x%P;
return ret;
}
inline void Pre(const int x){
mu[1]=1;
for(int i=2;i<=x;i++){
if(!p[i]) p[++*p]=i,mu[i]=-1;
for(int j=1;j<=*p && 1LL*p[j]*i<=x;j++)
if(p[p[j]*i]=1,i%p[j]) mu[i*p[j]]=-mu[i];
else{
mu[i*p[j]]=0; break;
}
}
for(int i=1;i<=x;i++) g[i]=1;
f[1]=f[2]=1;
for(int i=3;i<=x;i++) f[i]=(f[i-1]+f[i-2])%P;
for(int i=2;i<=x;i++){
int INV=Pow(f[i],P-2);
for(int j=i;j<=x;j+=i){
if(mu[j/i]==0) continue;
if(mu[j/i]==-1) g[j]=1LL*g[j]*INV%P;
else g[j]=1LL*g[j]*f[i]%P;
}
}
h[0]=invh[0]=1;
for(int i=1;i<=x;i++) h[i]=1LL*h[i-1]*g[i]%P,invh[i]=Pow(h[i],P-2);
}
int ans;
int main(){
scanf("%d",&t); Pre(N-10);
while(t--){
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
ans=1;
for(int i=1,nxt;i<=n;i=nxt+1){
nxt=min(n/(n/i),m/(m/i));
ans=1LL*ans*Pow(1LL*h[nxt]*invh[i-1]%P,1LL*(n/i)*(m/i))%P;
}
printf("%d\n",ans);
}
return 0;
}