//费马小定理
ll qpow(ll a,ll b,ll m){
ll res=1;
while(b){
if(b&1){
res=res*a%m;
}
a=a*a%m;
b>>=1;
}
return res;
}
ll inv(ll a,ll m){
return qpow(a,m-2,m);
}
//扩展欧几里得
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;
y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
ll inv(ll a,ll m){
ll x,y;
exgcd(a,m,x,y);
return (x%m+m)%m;
}
//线性递推
inv[1]=1;
for(int i=2;i<=n;i++)
inv[i]=(m-m/i)*inv[m%i]%m;
//阶乘逆元
fac[0]=1;
for(int i=1;i<=n;i++){
fac[i]=fac[i-1]*i%m;
}
ifac[n]=qpow(fac[n],m-2,m);
for(int i=n;i>=1;i--){
ifac[i-1]=ifac[i]*i%m;
}
// 则 C(n,k) = fac[n] * ifac[k] % m * ifac[n-k] % m