链接:http://poj.org/problem?id=2154
//#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 33333
#define MAXM 2000010
int gcd(int a, int b)
{
if(a==0)return b;
return gcd(b%a,a);
}
int prime[MAXN];
void get_prime()
{
memset(prime,0,sizeof(prime));
for(int i=2; i<MAXN; ++i)
{
if(!prime[i])prime[++prime[0]]=i;
for(int j=1; j<=prime[0]&&prime[j]<MAXN/i; ++j)
{
prime[ prime[j]*i ]=1;
if(prime[i%prime[j]]==0)break;
}
}
}
long long eular(long long n)
{
long long ans=n;
for(int i=1; prime[i]*prime[i]<=n; ++i)
{
if(n%prime[i]==0)
{
ans-=ans/prime[i];
while(n%prime[i]==0)n/=prime[i];
}
}
if(n>1)ans-=ans/n;
return ans;
}
long long quick_pow(long long x, long long n, long long mod)
{
long long ans=1;
x%=mod;
while(n)
{
if(n&1)ans=ans*x%mod;
x=x*x%mod;
n>>=1;
}
return ans;
}
int main()
{
int p,n;
int m;
get_prime();
scanf("%d",&m);
for(int j=0; j<m; ++j)
{
scanf("%d%d",&n,&p);
if(n==-1)break;
//n%=p;
if(n==0)
{
puts("0");
continue;
}
long long ans=0;
for(int i=1; i*i<=n; ++i)
{
if(n%i==0)
{
if(i*i==n)
ans=ans+eular(i)*quick_pow(n,i-1,p)%p;
else
ans=ans+eular(n/i)*quick_pow(n,i-1,p)%p+eular(i)*quick_pow(n,n/i-1,p)%p;
ans%=p;
}
}
printf("%I64d\n",ans);
}
return 0;
}