use core::ops::{BitAnd, Mul, MulAssign, Rem, RemAssign, ShrAssign};
pub fn bin_pow<N>(mut base: N, mut exp: u8) -> N
where N: MulAssign + From<u8> + Copy {
let mut vi = N::from(1);
while exp != 0 {
if (exp & 1) != 0 {
vi *= base;
}
base *= base;
exp >>= 1;
}
vi
}
pub fn modpow<N>(mut base: N, mut exp: N, modulo: N) -> N
where N: Mul<Output = N> + Rem<Output = N> + RemAssign + From<u8> + Copy + Eq + BitAnd<Output = N> + ShrAssign<i32> {
let mut res = 1.into();
base %= modulo;
while exp != 0.into() {
if exp & 1.into() == 1.into() {
res = (res * base) % modulo;
}
exp >>= 1;
base = (base * base) % modulo;
}
res
}