首先考虑当
n
n
有平方因子时,取
a=p
a
=
p
就无解了,所以我们只考虑
μ2(n)=1
μ
2
(
n
)
=
1
的情况。
考虑中国剩余定理,只要保证对于
n
n
的每个因子满足对于所有
a
a
,求最小的,使得
ank≡a(modpi)
a
n
k
≡
a
(
mod
p
i
)
,即
nk≡1(modpi−1)
n
k
≡
1
(
mod
p
i
−
1
)
。
显然当
gcd(n,pi−1)>1
gcd
(
n
,
p
i
−
1
)
>
1
的时候无解,否则最小的
k
k
就是求在
(modpi−1)
(
mod
p
i
−
1
)
意义下的阶,那么
k|φ(pi−1)
k
|
φ
(
p
i
−
1
)
,暴力枚举
φ(pi−1)
φ
(
p
i
−
1
)
的约数判一下就可以了。
最后的答案就是
lcm{ki}
lcm
{
k
i
}
。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define fs first
#define sc second
#define ll long long
#define vpli vector<pair<ll,int> >
using namespace std;
int pri[6]={2,3,7,61,10007,24251};
ll rd()
{
return (rand()<<31)+rand();
}
ll mul(ll a,ll b,ll mod)
{
a=(a>=mod?a%mod:a);
b=(b>=mod?b%mod:b);
ll tmp=(a*b-(ll)((long double)a/mod*b+1e-2)*mod);
return tmp<0?tmp+mod:tmp;
}
ll gcd(ll x,ll y)
{
ll t;
if(x<y) t=x,x=y,y=t;
while(y) t=x,x=y,y=t%y;
return x;
}
ll lcm(ll x,ll y)
{
return x/gcd(x,y)*y;
}
ll ksm(ll a,ll b,ll mod)
{
ll r=1;
for(;b;b>>=1)
{
if(b&1) r=mul(r,a,mod);
a=mul(a,a,mod);
}
return r;
}
ll MR(ll n)
{
ll r=n-1,s=0;
while(!(r&1)) r>>=1,s++;
for(int i=0;i<6;i++)
{
if(n==pri[i]) return 1;
ll t=ksm(pri[i],r,n),u=t;
for(int j=1;j<=s;j++)
{
t=mul(t,t,n);
if(t==1&&u!=1&&u!=n-1) return 0;
u=t;
}
if(t!=1) return 0;
}
return 1;
}
ll rho(ll n)
{
ll a=rd()%n,b=a,c=rd()%n,k=1,d=1;
for(ll i=1;d==1;i++)
{
b=(mul(b,b,n)+c)%n;
d=gcd(a>b?a-b:b-a,n);
if(i==k) k<<=1,a=b;
}
if(d==n) return rho(n);
return d;
}
void solve(ll n,vpli &p)
{
if(n<=1) return ;
if(MR(n))
{
for(int i=0;i<p.size();i++)
if(p[i].fs==n) {p[i].sc++;return ;}
p.push_back(make_pair(n,1));
return ;
}
ll t=rho(n);
solve(t,p),solve(n/t,p);
}
ll phi(ll x)
{
vpli p;solve(x,p);
ll re=x;
for(int i=0;i<p.size();i++)
re=re/p[i].fs*(p[i].fs-1);
return re;
}
ll qk(ll n,ll mod)
{
vpli p;
ll k=phi(mod);
solve(k,p);
for(int i=0;i<p.size();i++)
while(p[i].sc&&ksm(n,k/p[i].fs,mod)==1) k/=p[i].fs,p[i].sc--;
return k;
}
int main()
{
srand(666623333);
ll n,ans=1;
vpli p;
scanf("%lld",&n);
solve(n,p);
for(int i=0;i<p.size();i++)
if(p[i].sc>1||gcd(n,p[i].fs-1)>1) {puts("-1");return 0;}
for(int i=0;i<p.size();i++)
ans=lcm(ans,qk(n,p[i].fs-1));
printf("%lld",ans);
return 0;
}