// codesnip-guard: FastPrimeMod #[cfg_attr(any(),rustfmt::skip)]pub use self::fast_prime_mod::FastPrimeMod;#[cfg_attr(any(),rustfmt::skip)]mod fast_prime_mod{use super::{Xorshift,miller_rabin,primitive_root};const K:usize=1<<21;const POW_BLOCK_BITS:u32=15;const POW_BLOCK:usize=1<()->bool{P as usize<=K}const fn table_k()->usize{if is_direct_table_mod::

(){P as usize-1}else{K}}const fn table_len()->usize{2*table_k::

()+1}#[doc=" Fast online inverse and power queries for a prime modulus."]pub struct FastPrimeMod{root:u32,pow_lo:Box<[u32]>,pow_hi:Box<[u32]>,frac:Box<[u32]>,log:Box<[u32]>,inv:Box<[u32]>}implFastPrimeMod{#[doc=" Builds the tables enabled by the const generic mode."]#[doc=""]#[doc=" # Panics"]#[doc=""]#[doc=" Panics if `P` is not an odd prime or if `P >= 2^30`."]pub fn new()->Self{assert!(BUILD_INV||BUILD_POW,"at least one of BUILD_INV or BUILD_POW must be true");assert!(P<1<<30,"P must be less than 2^30");assert!(P%2==1&&miller_rabin(P as u64),"P must be an odd prime");let(root,pow_lo,pow_hi,log)=if BUILD_POW{let root=if P==998_244_353{3}else{primitive_root(P as u64)as u32};let(pow_lo,pow_hi)=build_pow::

(root);let log=build_log::

(root,&pow_lo,&pow_hi);(root,pow_lo,pow_hi,log)}else{(0,Vec::new().into_boxed_slice(),Vec::new().into_boxed_slice(),Vec::new().into_boxed_slice())};let inv=if BUILD_INV{build_inv::

()}else{Vec::new().into_boxed_slice()};let frac=if is_direct_table_mod::

(){Vec::new().into_boxed_slice()}else{build_frac::

()};Self{root,pow_lo,pow_hi,frac,log,inv}}#[doc=" Returns the prime modulus."]#[inline]pub fn modulus(&self)->u32{P}#[inline(always)]fn small_fraction(&self,x:u32)->(usize,u32){let k=table_k::

();if is_direct_table_mod::

(){debug_assert!(1<=x&&x>FRAC_SHIFT)as usize];let a=packed>>16;let b=packed&0xffff;let t=x.wrapping_mul(b).wrapping_sub(a.wrapping_mul(P));debug_assert!({let t=x as i64*b as i64-a as i64*P as i64;t!=0&&-(k as i64)<=t&&t<=k as i64});((k as u32).wrapping_add(t)as usize,b)}}implFastPrimeMod{#[doc=" Returns `x^{-1} mod P`."]#[doc=""]#[doc=" # Panics"]#[doc=""]#[doc=" Panics unless `1 <= x < P`."]#[inline]pub fn inverse(&self,x:u32)->u32{assert!(1<=x&&x(self.inv[i],b)}}implFastPrimeMod{#[doc=" Returns the primitive root used by this table."]#[inline]pub fn primitive_root(&self)->u32{self.root}#[doc=" Returns `a^exp mod P`."]#[doc=""]#[doc=" `0^0` is defined as `1`."]#[doc=""]#[doc=" # Panics"]#[doc=""]#[doc=" Panics unless `a < P`."]#[inline]pub fn pow(&self,a:u32,exp:u64)->u32{assert!(au32{assert!(1<=a&&au32{assert!(exp_mod(exp_mod,&self.pow_lo,&self.pow_hi)}#[inline]fn log_r(&self,x:u32)->u32{let(i,b)=self.small_fraction(x);let k=table_k::

();let ord=P-1;self.log[i]+ord-self.log[k+b as usize]}}implDefault for FastPrimeMod{fn default()->Self{Self::new()}}fn build_pow(root:u32)->(Box<[u32]>,Box<[u32]>){let mut pow_lo=vec![0;POW_BLOCK+1].into_boxed_slice();let mut pow_hi=vec![0;POW_BLOCK+1].into_boxed_slice();pow_lo[0]=1;pow_hi[0]=1;for i in 0..POW_BLOCK{pow_lo[i+1]=mul_mod_raw::

(pow_lo[i],root);}let block_power=pow_lo[POW_BLOCK];for i in 0..POW_BLOCK{pow_hi[i+1]=mul_mod_raw::

(pow_hi[i],block_power);}(pow_lo,pow_hi)}fn build_inv()->Box<[u32]>{let k=table_k::

();let mut inv=vec![0;table_len::

()].into_boxed_slice();inv[k+1]=1;for i in 2..=k{let q=P.div_ceil(i as u32);let r=i as u32*q-P;inv[k+i]=mul_mod_raw::

(inv[k+r as usize],q);}for i in 1..=k{inv[k-i]=P-inv[k+i];}inv}fn build_log(root:u32,pow_lo:&[u32],pow_hi:&[u32])->Box<[u32]>{let k=table_k::

();let ord=P-1;let mut lpf=vec![0;k+1].into_boxed_slice();let mut primes=vec![];lpf[1]=1;for i in 2..=k{if lpf[i]==0{lpf[i]=i as u32;primes.push(i as u32);}for&p in primes.iter(){let p=p as usize;if p>lpf[i]as usize||p>k/i{break;}lpf[i*p]=p as u32;}}let baby_size=(BSGS_SIZE as u32).min(ord);let mut baby=U32Map::new(baby_size as usize);let mut pw=1;for i in 0..baby_size{baby.insert(pw,i);pw=mul_mod_raw::

(pw,root);}let q=pow_root_raw::

(ord-baby_size,pow_lo,pow_hi);let mut log=vec![0;table_len::

()].into_boxed_slice();log[k+1]=0;let mut rng=Xorshift::default();let small_primes=[2,3,5,7,11,13,17,19];for i in 2..=k{let p=lpf[i]as usize;if p(x,q);}}else if i>P as usize/i{let j=(P as usize)/i;let r=(P as usize)%i;let x=add_mod(log[k+r],ord/2,ord);let y=log[k+j];log[k+i]=if x>=y{x-y}else{x+ord-y};}else{loop{let exp=rng.rand(ord as u64)as u32;let mut ans=if exp==0{0}else{ord-exp};let mut x=mul_mod_raw::

(i as u32,pow_root_raw::

(exp,pow_lo,pow_hi));for q in small_primes{while x.is_multiple_of(q){x/=q;ans=add_mod(ans,log[k+q as usize],ord);}}if x as usize>=k{continue;}while(i as u32)()->Box<[u32]>{let mut frac=vec![0;FRAC_LEN].into_boxed_slice();let mut stack=vec![(0u16,1u16,1u16,1u16)];while let Some((a,b,c,d))=stack.pop(){let nb=b+d;if nb(exp:u32,pow_lo:&[u32],pow_hi:&[u32])->u32{let lo=exp as usize&(POW_BLOCK-1);let hi=exp as usize>>POW_BLOCK_BITS;mul_mod_raw::

(pow_lo[lo],pow_hi[hi])}#[inline(always)]fn mul_mod_raw(a:u32,b:u32)->u32{(a as u64*b as u64%P as u64)as u32}#[inline]fn add_mod(a:u32,b:u32,m:u32)->u32{let c=a+b;if c>=m{c-m}else{c}}#[inline]fn pack_frac(a:u16,b:u16)->u32{(a as u32)<<16|b as u32}struct U32Map{keys:Box<[u32]>,values:Box<[u32]>,mask:usize}impl U32Map{fn new(capacity:usize)->Self{let len=(capacity*2).next_power_of_two();Self{keys:vec![0;len].into_boxed_slice(),values:vec![0;len].into_boxed_slice(),mask:len-1}}fn insert(&mut self,key:u32,value:u32){debug_assert_ne!(key,0);let mut i=self.index(key);while self.keys[i]!=0&&self.keys[i]!=key{i=(i+1)&self.mask;}self.keys[i]=key;self.values[i]=value;}fn get(&self,key:u32)->Option{debug_assert_ne!(key,0);let mut i=self.index(key);while self.keys[i]!=0{if self.keys[i]==key{return Some(self.values[i]);}i=(i+1)&self.mask;}None}#[inline]fn index(&self,key:u32)->usize{let mut x=key as u64;x=(x^(x>>30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);x=(x^(x>>27)).wrapping_mul(0x94d0_49bb_1331_11eb);((x^(x>>31))as usize)&self.mask}}} // codesnip-guard: BarrettReduction #[cfg_attr(any(),rustfmt::skip)]pub use self::barrett_reduction::{BarrettReduction,Barrettable};#[cfg_attr(any(),rustfmt::skip)]mod barrett_reduction{use super::{One,Zero};use std::ops::{Add,Mul,Sub};#[derive(Debug,Clone,Copy)]pub struct BarrettReduction{m:T,im:T}implBarrettReductionwhere T:Barrettable{pub fn new(m:T)->Self{Self{m,im:T::inv_mod_approx(m)}}pub const fn new_with_im(m:T,im:T)->Self{Self{m,im}}pub const fn get_mod(&self)->T{self.m}pub fn div_rem(&self,a:T)->(T,T){T::barrett_reduce(a,self.m,self.im)}pub fn div(&self,a:T)->T{self.div_rem(a).0}pub fn rem(&self,a:T)->T{self.div_rem(a).1}}pub trait Barrettable:Sized+Copy+PartialOrd+Zero+One+Add+Sub+Mul{fn inv_mod_approx(m:Self)->Self;fn div_approx(self,im:Self)->Self;fn barrett_reduce(self,m:Self,im:Self)->(Self,Self){if m==Self::one(){return(self,Self::zero());}let q=self.div_approx(im);let r=self-q*m;if m<=r{(q+Self::one(),r-m)}else{(q,r)}}}impl Barrettable for u32{fn inv_mod_approx(m:Self)->Self{!0/m}fn div_approx(self,im:Self)->Self{((self as u64*im as u64)>>32)as u32}}impl Barrettable for u64{fn inv_mod_approx(m:Self)->Self{!0/m}fn div_approx(self,im:Self)->Self{((self as u128*im as u128)>>64)as u64}}impl Barrettable for u128{fn inv_mod_approx(m:Self)->Self{!0/m}fn div_approx(self,im:Self)->Self{const MASK64:u128=0xffff_ffff_ffff_ffff;let au=self>>64;let ad=self&MASK64;let imu=im>>64;let imd=im&MASK64;let res=au*imu;let x=((ad*imd)>>64)+au*imd;let(x,c)=x.overflowing_add(ad*imu);res+((c as u128)<<64)+(x>>64)}}} // codesnip-guard: Xorshift #[cfg_attr(any(),rustfmt::skip)]pub use self::xorshift::Xorshift;#[cfg_attr(any(),rustfmt::skip)]mod xorshift{use std::{collections::hash_map::RandomState,hash::{BuildHasher,Hasher},iter::repeat_with};#[derive(Clone,Debug)]pub struct Xorshift{y:u64}impl Xorshift{pub fn new_with_seed(seed:u64)->Self{Xorshift{y:seed}}pub fn new()->Self{Xorshift::new_with_seed(RandomState::new().build_hasher().finish())}pub fn rand64(&mut self)->u64{self.y^=self.y<<5;self.y^=self.y>>17;self.y^=self.y<<11;self.y}pub fn rand(&mut self,k:u64)->u64{self.rand64()%k}pub fn rands(&mut self,k:u64,n:usize)->Vec{repeat_with(| |self.rand(k)).take(n).collect()}pub fn randf(&mut self)->f64{const UPPER_MASK:u64=0x3FF0_0000_0000_0000;const LOWER_MASK:u64=0x000F_FFFF_FFFF_FFFF;let x=self.rand64();let tmp=UPPER_MASK|(x&LOWER_MASK);let result:f64=f64::from_bits(tmp);f64::from_bits(f64::to_bits(result-1.0)^(x>>63))}pub fn gen_bool(&mut self,p:f64)->bool{self.randf()(&mut self,slice:&mut[T]){let mut n=slice.len();while n>1{let i=self.rand(n as _)as usize;n-=1;slice.swap(i,n);}}}impl Default for Xorshift{fn default()->Self{Xorshift::new_with_seed(0x2b99_2ddf_a232_49d6)}}} // codesnip-guard: gcd #[cfg_attr(any(),rustfmt::skip)]#[doc=" binary gcd"]pub fn gcd(mut a:u64,mut b:u64)->u64{if a==0{return b;}if b==0{return a;}let u=a.trailing_zeros();let v=b.trailing_zeros();a>>=u;b>>=v;let k=std::cmp::min(u,v);while a!=b{if a>=a.trailing_zeros();}a<{fn$name(n:$ty,br:&BarrettReduction<$upty>,a:$ty)->bool{if br.rem(a as$upty)==0{return true;}let d=n-1;let k=d.trailing_zeros();let mut d=d>>k;let mut y={let mut a=a as$upty;let mut y:$upty=1;while d>0{if d&1==1{y=br.rem(y*a);}a=br.rem(a*a);d>>=1;}y as$ty};if y==1||y==n-1{true}else{for _ in 0..k-1{y=br.rem(y as$upty*y as$upty)as$ty;if y==n-1{return true;}}false}}};}impl_test_mr!(test_mr32,u32,u64);impl_test_mr!(test_mr64,u64,u128);#[doc=" "]macro_rules!impl_mr{($name:ident,$test:ident,$ty:ty,$upty:ty,[$($th:expr,[$($a:expr),+]),+],|$n:ident,$br:ident|$last:expr)=>{fn$name($n:$ty,$br:&BarrettReduction<$upty>)->bool{$(if$n>=$th{return$($test($n,$br,$a))&&+})+$last}};}impl_mr!(mr32,test_mr32,u32,u64,[316349281,[2,7,61],49141,[11000544,31481107]],|n,br|test_mr32(n,br,921211727));impl_mr!(mr64,test_mr64,u64,u128,[585226005592931977,[2,325,9375,28178,450775,9780504,1795265022],7999252175582851,[2,123635709730000,9233062284813009,43835965440333360,761179012939631437,1263739024124850375],55245642489451,[2,4130806001517,149795463772692060,186635894390467037,3967304179347715805],350269456337,[2,141889084524735,1199124725622454117,11096072698276303650],1050535501,[4230279247111683200,14694767155120705706,16641139526367750375]],|n,br|mr32(n as u32,&BarrettReduction::::new(n)));pub fn miller_rabin_with_br(n:u64,br:&BarrettReduction)->bool{if n.is_multiple_of(2){return n==2;}if n.is_multiple_of(3){return n==3;}if n.is_multiple_of(5){return n==5;}if n.is_multiple_of(7){return n==7;}if n<121{n>2}else{mr64(n,br)}}pub fn miller_rabin(n:u64)->bool{n>=2&&miller_rabin_with_br(n,&BarrettReduction::::new(n as u128))}} // codesnip-guard: prime_factors #[cfg_attr(any(),rustfmt::skip)]pub use self::prime_factors::{divisors,prime_factors,prime_factors_flatten};#[cfg_attr(any(),rustfmt::skip)]mod prime_factors{use super::{BarrettReduction,Xorshift,gcd,miller_rabin_with_br};struct MontgomeryReduction64{modulus:u64,inverse:u64}impl MontgomeryReduction64{fn new(modulus:u64)->Self{let mut inverse=modulus;for _ in 0..6{inverse=inverse.wrapping_mul(2u64.wrapping_sub(modulus.wrapping_mul(inverse)));}Self{modulus,inverse}}fn sub(&self,lhs:u64,rhs:u64)->u64{let(value,borrow)=lhs.overflowing_sub(rhs);value.wrapping_add((borrow as u64).wrapping_neg()&self.modulus)}fn mul(&self,lhs:u64,rhs:u64)->u64{let product=lhs as u128*rhs as u128;let(value,borrow)=((product>>64)as u64).overflowing_sub((((product as u64).wrapping_mul(self.inverse)as u128*self.modulus as u128)>>64)as u64);value.wrapping_add((borrow as u64).wrapping_neg()&self.modulus)}}fn find_factor(n:u64)->Option{let br=BarrettReduction::::new(n as u128);if miller_rabin_with_br(n,&br){return None;}let mr=MontgomeryReduction64::new(n);let mut rng=Xorshift::default();let(mut y0,mut c)=(0,n-1);loop{let(mut x,mut y,mut ys,mut g,mut q,mut r,mut k)=(0,y0,0,1,1,1,0);while g==1&&r<=1<<20{x=y;while k>64)as u64+2;c=((rng.rand64()as u128*(n-1)as u128)>>64)as u64+1;}}pub fn prime_factors_flatten(mut n:u64)->Vec{if n==0{return vec![];}let k=n.trailing_zeros();let mut res=vec![2;k as usize];n>>=k;while n.is_multiple_of(3){res.push(3);n/=3;}if n!=1{let mut c=vec![n];while let Some(n)=c.pop(){if let Some(m)=find_factor(n){c.push(m);c.push(n/m);}else{res.push(n);}}}res.sort_unstable();res}pub fn prime_factors(n:u64)->Vec<(u64,u32)>{let mut res=Vec::new();for a in prime_factors_flatten(n){if let Some((p,len))=res.last_mut()&&p==&a{*len+=1;continue;}res.push((a,1));}res}pub fn divisors(n:u64)->Vec{let mut d=vec![1u64];for(p,c)in prime_factors(n){let k=d.len();let mut acc=1;for _ in 0..c{acc*=p;for i in 0..k{d.push(d[i]*acc);}}}d.sort_unstable();d}} // codesnip-guard: primitive_root #[cfg_attr(any(),rustfmt::skip)]pub use self::primitive_root::{check_primitive_root,primitive_root};#[cfg_attr(any(),rustfmt::skip)]mod primitive_root{use super::{BarrettReduction,Xorshift,prime_factors};pub fn primitive_root(p:u64)->u64{if p==2{return 1;}let phi=p-1;let pf=prime_factors(phi);let br=BarrettReduction::::new(p as _);for g in 2..=3.min(p-1){if check_primitive_root(g,phi,&br,&pf){return g;}}let mut rng=Xorshift::default();loop{let g=((rng.rand64()as u128*(p-2)as u128)>>64)as u64+2;if check_primitive_root(g,phi,&br,&pf){return g;}}}pub fn check_primitive_root(g:u64,phi:u64,br:&BarrettReduction,pf:&[(u64,u32)])->bool{pf.iter().all(|&(q,_)|{let mut g=g as u128;let mut k=phi/q;let mut r:u128=1;while k>0{if k&1==1{r=br.rem(r*g);}g=br.rem(g*g);k>>=1;}r>1})}} // codesnip-guard: zero_one #[cfg_attr(any(),rustfmt::skip)]pub use self::zero_one::{One,Zero};#[cfg_attr(any(),rustfmt::skip)]mod zero_one{pub trait Zero:Sized{fn zero()->Self;#[inline]fn is_zero(&self)->bool where Self:PartialEq{self==&Self::zero()}#[inline]fn set_zero(&mut self){*self=Self::zero();}}pub trait One:Sized{fn one()->Self;#[inline]fn is_one(&self)->bool where Self:PartialEq{self==&Self::one()}#[inline]fn set_one(&mut self){*self=Self::one();}}macro_rules!impl_zero_one{($({$(<$T:ident:$Bound:ident>)?$Trait:ident$method:ident$($t:ty)*,$e:expr})*)=>{$(impl_zero_one!(@impl[$(<$T:$Bound>)?]$Trait$method[$($t)*],$e);)*};(@impl[<$T:ident:$Bound:ident>]$Trait:ident$method:ident[$($t:ty)*],$e:expr)=>{$(impl<$T:$Bound>$Trait for$t{fn$method()->Self{$e}})*};(@impl[]$Trait:ident$method:ident[$($t:ty)*],$e:expr)=>{$(impl$Trait for$t{fn$method()->Self{$e}})*};}impl_zero_one!({Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128,0}{Zero zero f32 f64,0.}{One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128,1}{One one f32 f64,1.}{Zero zero std::num::Wrapping,Self(T::zero())}{One one std::num::Wrapping,Self(T::one())});}