( ext{Description})
- ( ext{Given a number }p(pleqslant10^7).)
- ( ext{Output }2^{2^{2^{2^{cdots}}}}mod p.)
( ext{Method})
( ext{Use ex-Euler's Theorem}quad bgeqslantvarphi(m)Rightarrow a^bequiv a^{bmodvarphi(m)+varphi(m)}pmod{m}.)
( ext{Let }x=2^{2^{2^{2^{cdots}}}}.)
[egin{aligned}xmod p& =2^xmod p\& =2^{xmod varphi(p)+varphi(p)}mod p\& =2^{2^xmod varphi(p)+varphi(p)}mod p\& =2^{2^{xmod varphi(varphi(p))+varphi(p)}mod varphi(p)+varphi(p)}mod p\&=cdotsend{aligned}
]
( ext{Use recursion algorithm.Let }f(i)=xmod i.)
[f(i)=egin{cases}0&i=1\2^{f(varphi(i))+varphi(i)}mod i&i>1end{cases}
]
( ext{Code})
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int qmul(int a,int b,int mod)
{
if(a==0||b==0||mod==1ll)return 0;
if(b==1ll)return a%mod;
int ans=qmul(a,b/2ll,mod);
ans+=ans,ans%=mod;
if(b%2ll)ans+=a,ans%=mod;
return ans;
}
int qpow(int a,int b,int mod)
{
if(a==0||mod==1ll)return 0;
if(b==0)return 1ll;
int ans=qpow(a,b/2ll,mod);
ans=qmul(ans,ans,mod),ans%=mod;
if(b%2ll)ans=qmul(ans,a,mod),ans%=mod;
return ans;
}
int v[10000010],prime[10000010],phi[10000010];
void lineareuler(int n)
{
memset(v,0,sizeof(v));
int cnt=0;
for(int i=2;i<=n;i++)
{
if(v[i]==0)
{
v[i]=i;
prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++)
{
if(prime[j]>v[i]||prime[j]>n/i)break;
v[i*prime[j]]=prime[j];
phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
}
}
return;
}
int calc(int xx)
{
if(xx==1)return 0;
else return qpow(2,calc(phi[xx])+phi[xx],xx);
}
int t,p;
int main()
{
scanf("%d",&t);
lineareuler(10000000);
for(int qwerty=1;qwerty<=t;qwerty++)
{
scanf("%d",&p);
printf("%d
",calc(p));
}
return 0;
}