global_init!(G: Vec>, vec![vec![]]); global_init!(TREE_SIZE: Vec, vec![]); global_init!(ANS: ModInt1000000007, ModInt1000000007::new(0)); global_init!(BASE: ModInt1000000007, ModInt1000000007::new(0)); global_init!(N: ModInt1000000007, ModInt1000000007::new(0)); fn dfs(k: usize, p: usize) { if k != p && gl!(G)[k].len() == 1 { glm!(TREE_SIZE)[k] = 1; return; } let mut r = 1; for &(i, s) in &gl!(G)[k] { if i == p { continue; } dfs(i, k); r += gl!(TREE_SIZE)[i]; *glm!(ANS) += ModInt1000000007::new(gl!(TREE_SIZE)[i]) * (*gl!(N) - ModInt1000000007::new(gl!(TREE_SIZE)[i])) * glm!(BASE).pow(s as u64); } glm!(TREE_SIZE)[k] = r; } fn main() { input! { n:usize,m:usize,x:usize } *glm!(N) = ModInt1000000007::new(n); *glm!(BASE) = ModInt1000000007::new(x); let mut uf = Dsu::new(n); *glm!(G) = vec![vec![]; n]; *glm!(TREE_SIZE) = vec![0; n]; for _ in 0..m { input! { x:usize,y:usize,z:usize } if !uf.same(x - 1, y - 1) { uf.merge(x - 1, y - 1); glm!(G)[x - 1].push((y - 1, z)); glm!(G)[y - 1].push((x - 1, z)); } } dfs(0, 0); //dbg!(gl!(TREE_SIZE)); println!("{}", gl!(ANS)); } //https://github.com/rust-lang-ja/ac-library-rs //https://github.com/manta1130/competitive-template-rs pub mod dsu { pub struct Dsu { n: usize, parent_or_size: Vec, } impl Dsu { pub fn new(size: usize) -> Self { Self { n: size, parent_or_size: vec![-1; size], } } pub fn merge(&mut self, a: usize, b: usize) -> usize { assert!(a < self.n); assert!(b < self.n); let (mut x, mut y) = (self.leader(a), self.leader(b)); if x == y { return x; } if -self.parent_or_size[x] < -self.parent_or_size[y] { std::mem::swap(&mut x, &mut y); } self.parent_or_size[x] += self.parent_or_size[y]; self.parent_or_size[y] = x as i32; x } pub fn same(&mut self, a: usize, b: usize) -> bool { assert!(a < self.n); assert!(b < self.n); self.leader(a) == self.leader(b) } pub fn leader(&mut self, a: usize) -> usize { assert!(a < self.n); if self.parent_or_size[a] < 0 { return a; } self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32; self.parent_or_size[a] as usize } pub fn size(&mut self, a: usize) -> usize { assert!(a < self.n); let x = self.leader(a); -self.parent_or_size[x] as usize } pub fn groups(&mut self) -> Vec> { let mut leader_buf = vec![0; self.n]; let mut group_size = vec![0; self.n]; for i in 0..self.n { leader_buf[i] = self.leader(i); group_size[leader_buf[i]] += 1; } let mut result = vec![Vec::new(); self.n]; for i in 0..self.n { result[i].reserve(group_size[i]); } for i in 0..self.n { result[leader_buf[i]].push(i); } result .into_iter() .filter(|x| !x.is_empty()) .collect::>>() } } } pub mod global { pub use std::cell::RefCell; pub use std::rc::Rc; use std::thread::LocalKey; #[macro_export] #[allow(unused_macros)] macro_rules! global_init { ($x:ident : $t:ty,$i:expr) => { thread_local! { pub static $x:Rc>=Rc::new(RefCell::new($i)); } }; } #[macro_export] #[allow(unused_macros)] macro_rules! glm { ($x:ident) => { global_access(&($x)).borrow_mut() }; } #[macro_export] #[allow(unused_macros)] macro_rules! gl { ($x:ident) => { global_access(&($x)).borrow() }; } pub fn global_access(p: &'static LocalKey>>) -> Rc> { p.with(|q| q.clone()) } } pub mod input { use std::cell::RefCell; use std::io; pub const SPLIT_DELIMITER: char = ' '; pub use std::io::prelude::*; #[macro_export] thread_local! { pub static INPUT_BUFFER:RefCell>=RefCell::new(std::collections::VecDeque::new()); } #[macro_export] #[allow(unused_macros)] macro_rules! input { ( $($x:ident : $t:ty),*) => { $( INPUT_BUFFER.with(|p| if p.borrow().len()==0{ let temp_str = input_line_str(); let mut split_result_iter = temp_str.split(SPLIT_DELIMITER).map(|q|q.to_string()).collect::>(); p.borrow_mut().append(&mut split_result_iter) }); let mut buf_split_result=String::new(); INPUT_BUFFER.with(|p| buf_split_result = p.borrow_mut().pop_front().unwrap()); let ($x):($t) = buf_split_result.parse().unwrap(); )* }; } #[macro_export] #[allow(unused_macros)] macro_rules! input_all { ( $($x:ident : $t:ty),*) => { $( INPUT_BUFFER.with(|p| if p.borrow().len()==0{ let mut temp_str = String::new(); std::io::stdin().read_to_string(&mut temp_str).unwrap(); let mut split_result_iter = temp_str.split_whitespace().map(|q|q.to_string()).collect::>(); p.borrow_mut().append(&mut split_result_iter) }); let mut buf_split_result=String::new(); INPUT_BUFFER.with(|p| buf_split_result = p.borrow_mut().pop_front().unwrap()); let ($x):($t) = buf_split_result.parse().unwrap(); )* }; } pub fn input_line_str() -> String { let mut s = String::new(); io::stdin().read_line(&mut s).unwrap(); s.trim().to_string() } #[allow(clippy::match_wild_err_arm)] pub fn input_vector() -> Vec where T: std::str::FromStr, { let mut v: Vec = Vec::new(); let s = input_line_str(); let split_result = s.split(SPLIT_DELIMITER); for z in split_result { let buf = match z.parse() { Ok(r) => r, Err(_) => panic!("Parse Error",), }; v.push(buf); } v } #[allow(clippy::match_wild_err_arm)] pub fn input_vector_row(n: usize) -> Vec where T: std::str::FromStr, { let mut v = Vec::with_capacity(n); for _ in 0..n { let buf = match input_line_str().parse() { Ok(r) => r, Err(_) => panic!("Parse Error",), }; v.push(buf); } v } pub trait ToCharVec { fn to_charvec(&self) -> Vec; } impl ToCharVec for String { fn to_charvec(&self) -> Vec { self.to_string().chars().collect::>() } } } pub mod internal_math { #![allow(dead_code)] use std::mem::swap; /* const */ pub(crate) fn safe_mod(mut x: i64, m: i64) -> i64 { x %= m; if x < 0 { x += m; } x } pub(crate) struct Barrett { pub(crate) _m: u32, pub(crate) im: u64, } impl Barrett { pub(crate) fn new(m: u32) -> Barrett { Barrett { _m: m, im: (-1i64 as u64 / m as u64).wrapping_add(1), } } pub(crate) fn umod(&self) -> u32 { self._m } #[allow(clippy::many_single_char_names)] pub(crate) fn mul(&self, a: u32, b: u32) -> u32 { let mut z = a as u64; z *= b as u64; let x = (((z as u128) * (self.im as u128)) >> 64) as u64; let mut v = z.wrapping_sub(x.wrapping_mul(self._m as u64)) as u32; if self._m <= v { v = v.wrapping_add(self._m); } v } } /* const */ #[allow(clippy::many_single_char_names)] pub(crate) fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 { if m == 1 { return 0; } let _m = m as u32; let mut r: u64 = 1; let mut y: u64 = safe_mod(x, m as i64) as u64; while n != 0 { if (n & 1) > 0 { r = (r * y) % (_m as u64); } y = (y * y) % (_m as u64); n >>= 1; } r as i64 } /* const */ pub(crate) fn is_prime(n: i32) -> bool { let n = n as i64; match n { _ if n <= 1 => return false, 2 | 7 | 61 => return true, _ if n % 2 == 0 => return false, _ => {} } let mut d = n - 1; while d % 2 == 0 { d /= 2; } for &a in &[2, 7, 61] { let mut t = d; let mut y = pow_mod(a, t, n as i32); while t != n - 1 && y != 1 && y != n - 1 { y = y * y % n; t <<= 1; } if y != n - 1 && t % 2 == 0 { return false; } } true } /* const */ #[allow(clippy::many_single_char_names)] pub(crate) fn inv_gcd(a: i64, b: i64) -> (i64, i64) { let a = safe_mod(a, b); if a == 0 { return (b, 0); } let mut s = b; let mut t = a; let mut m0 = 0; let mut m1 = 1; while t != 0 { let u = s / t; s -= t * u; m0 -= m1 * u; // |m1 * u| <= |m1| * s <= b swap(&mut s, &mut t); swap(&mut m0, &mut m1); } if m0 < 0 { m0 += b / s; } (s, m0) } /* const */ pub(crate) fn primitive_root(m: i32) -> i32 { match m { 2 => return 1, 167_772_161 => return 3, 469_762_049 => return 3, 754_974_721 => return 11, 998_244_353 => return 3, _ => {} } let mut divs = [0; 20]; divs[0] = 2; let mut cnt = 1; let mut x = (m - 1) / 2; while x % 2 == 0 { x /= 2; } for i in (3..std::i32::MAX).step_by(2) { if i as i64 * i as i64 > x as i64 { break; } if x % i == 0 { divs[cnt] = i; cnt += 1; while x % i == 0 { x /= i; } } } if x > 1 { divs[cnt] = x; cnt += 1; } let mut g = 2; loop { if (0..cnt).all(|i| pow_mod(g, ((m - 1) / divs[i]) as i64, m) != 1) { break g as i32; } g += 1; } } } pub mod modint { use crate::internal_math; use std::{ cell::RefCell, convert::{Infallible, TryInto as _}, fmt, hash::{Hash, Hasher}, iter::{Product, Sum}, marker::PhantomData, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}, str::FromStr, thread::LocalKey, }; pub type ModInt1000000007 = StaticModInt; pub type ModInt998244353 = StaticModInt; pub type ModInt = DynamicModInt; #[derive(Copy, Clone, Eq, PartialEq)] #[repr(transparent)] pub struct StaticModInt { val: u32, phantom: PhantomData M>, } impl StaticModInt { #[inline(always)] pub fn modulus() -> u32 { M::VALUE } #[inline] pub fn new(val: T) -> Self { Self::raw(val.rem_euclid_u32(M::VALUE)) } #[inline] pub fn raw(val: u32) -> Self { Self { val, phantom: PhantomData, } } #[inline] pub fn val(self) -> u32 { self.val } #[inline] pub fn pow(self, n: u64) -> Self { ::pow(self, n) } #[inline] pub fn inv(self) -> Self { if M::HINT_VALUE_IS_PRIME { if self.val() == 0 { panic!("attempt to divide by zero"); } debug_assert!( internal_math::is_prime(M::VALUE.try_into().unwrap()), "{} is not a prime number", M::VALUE, ); self.pow((M::VALUE - 2).into()) } else { Self::inv_for_non_prime_modulus(self) } } } impl ModIntBase for StaticModInt { #[inline(always)] fn modulus() -> u32 { Self::modulus() } #[inline] fn raw(val: u32) -> Self { Self::raw(val) } #[inline] fn val(self) -> u32 { self.val() } #[inline] fn inv(self) -> Self { self.inv() } } pub trait Modulus: 'static + Copy + Eq { const VALUE: u32; const HINT_VALUE_IS_PRIME: bool; fn butterfly_cache() -> &'static LocalKey>>>; } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] pub enum Mod1000000007 {} impl Modulus for Mod1000000007 { const VALUE: u32 = 1_000_000_007; const HINT_VALUE_IS_PRIME: bool = true; fn butterfly_cache() -> &'static LocalKey>>> { thread_local! { static BUTTERFLY_CACHE: RefCell>> = RefCell::default(); } &BUTTERFLY_CACHE } } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] pub enum Mod998244353 {} impl Modulus for Mod998244353 { const VALUE: u32 = 998_244_353; const HINT_VALUE_IS_PRIME: bool = true; fn butterfly_cache() -> &'static LocalKey>>> { thread_local! { static BUTTERFLY_CACHE: RefCell>> = RefCell::default(); } &BUTTERFLY_CACHE } } pub struct ButterflyCache { pub(crate) sum_e: Vec>, pub(crate) sum_ie: Vec>, } #[derive(Copy, Clone, Eq, PartialEq)] #[repr(transparent)] pub struct DynamicModInt { val: u32, phantom: PhantomData I>, } impl DynamicModInt { #[inline] pub fn modulus() -> u32 { I::companion_barrett().with(|bt| bt.borrow().umod()) } #[inline] pub fn set_modulus(modulus: u32) { if modulus == 0 { panic!("the modulus must not be 0"); } I::companion_barrett().with(|bt| *bt.borrow_mut() = Barrett::new(modulus)) } #[inline] pub fn new(val: T) -> Self { ::new(val) } #[inline] pub fn raw(val: u32) -> Self { Self { val, phantom: PhantomData, } } #[inline] pub fn val(self) -> u32 { self.val } #[inline] pub fn pow(self, n: u64) -> Self { ::pow(self, n) } #[inline] pub fn inv(self) -> Self { Self::inv_for_non_prime_modulus(self) } } impl ModIntBase for DynamicModInt { #[inline] fn modulus() -> u32 { Self::modulus() } #[inline] fn raw(val: u32) -> Self { Self::raw(val) } #[inline] fn val(self) -> u32 { self.val() } #[inline] fn inv(self) -> Self { self.inv() } } pub trait Id: 'static + Copy + Eq { fn companion_barrett() -> &'static LocalKey>; } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] pub enum DefaultId {} impl Id for DefaultId { fn companion_barrett() -> &'static LocalKey> { thread_local! { static BARRETT: RefCell = RefCell::default(); } &BARRETT } } pub struct Barrett(internal_math::Barrett); impl Barrett { #[inline] pub fn new(m: u32) -> Self { Self(internal_math::Barrett::new(m)) } #[inline] fn umod(&self) -> u32 { self.0.umod() } #[inline] fn mul(&self, a: u32, b: u32) -> u32 { self.0.mul(a, b) } } impl Default for Barrett { #[inline] fn default() -> Self { Self(internal_math::Barrett::new(998_244_353)) } } pub trait ModIntBase: Default + FromStr + From + From + From + From + From + From + From + From + From + From + From + From + Copy + Eq + Hash + fmt::Display + fmt::Debug + Neg + Add + Sub + Mul + Div + AddAssign + SubAssign + MulAssign + DivAssign { fn modulus() -> u32; fn raw(val: u32) -> Self; fn val(self) -> u32; fn inv(self) -> Self; #[inline] fn new(val: T) -> Self { Self::raw(val.rem_euclid_u32(Self::modulus())) } #[inline] fn pow(self, mut n: u64) -> Self { let mut x = self; let mut r = Self::raw(1); while n > 0 { if n & 1 == 1 { r *= x; } x *= x; n >>= 1; } r } } pub trait RemEuclidU32 { fn rem_euclid_u32(self, modulus: u32) -> u32; } macro_rules! impl_rem_euclid_u32_for_small_signed { ($($ty:tt),*) => { $( impl RemEuclidU32 for $ty { #[inline] fn rem_euclid_u32(self, modulus: u32) -> u32 { (self as i64).rem_euclid(i64::from(modulus)) as _ } } )* } } impl_rem_euclid_u32_for_small_signed!(i8, i16, i32, i64, isize); impl RemEuclidU32 for i128 { #[inline] fn rem_euclid_u32(self, modulus: u32) -> u32 { self.rem_euclid(i128::from(modulus)) as _ } } macro_rules! impl_rem_euclid_u32_for_small_unsigned { ($($ty:tt),*) => { $( impl RemEuclidU32 for $ty { #[inline] fn rem_euclid_u32(self, modulus: u32) -> u32 { self as u32 % modulus } } )* } } macro_rules! impl_rem_euclid_u32_for_large_unsigned { ($($ty:tt),*) => { $( impl RemEuclidU32 for $ty { #[inline] fn rem_euclid_u32(self, modulus: u32) -> u32 { (self % (modulus as $ty)) as _ } } )* } } impl_rem_euclid_u32_for_small_unsigned!(u8, u16, u32); impl_rem_euclid_u32_for_large_unsigned!(u64, u128); #[cfg(target_pointer_width = "32")] impl_rem_euclid_u32_for_small_unsigned!(usize); #[cfg(target_pointer_width = "64")] impl_rem_euclid_u32_for_large_unsigned!(usize); trait InternalImplementations: ModIntBase { #[inline] fn inv_for_non_prime_modulus(this: Self) -> Self { let (gcd, x) = internal_math::inv_gcd(this.val().into(), Self::modulus().into()); if gcd != 1 { panic!("the multiplicative inverse does not exist"); } Self::new(x) } #[inline] fn default_impl() -> Self { Self::raw(0) } #[inline] fn from_str_impl(s: &str) -> Result { Ok(s.parse::() .map(Self::new) .unwrap_or_else(|_| todo!("parsing as an arbitrary precision integer?"))) } #[inline] fn hash_impl(this: &Self, state: &mut impl Hasher) { this.val().hash(state) } #[inline] fn display_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&this.val(), f) } #[inline] fn debug_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&this.val(), f) } #[inline] fn neg_impl(this: Self) -> Self { Self::sub_impl(Self::raw(0), this) } #[inline] fn add_impl(lhs: Self, rhs: Self) -> Self { let modulus = Self::modulus(); let mut val = lhs.val() + rhs.val(); if val >= modulus { val -= modulus; } Self::raw(val) } #[inline] fn sub_impl(lhs: Self, rhs: Self) -> Self { let modulus = Self::modulus(); let mut val = lhs.val().wrapping_sub(rhs.val()); if val >= modulus { val = val.wrapping_add(modulus) } Self::raw(val) } fn mul_impl(lhs: Self, rhs: Self) -> Self; #[inline] fn div_impl(lhs: Self, rhs: Self) -> Self { Self::mul_impl(lhs, rhs.inv()) } } impl InternalImplementations for StaticModInt { #[inline] fn mul_impl(lhs: Self, rhs: Self) -> Self { Self::raw((u64::from(lhs.val()) * u64::from(rhs.val()) % u64::from(M::VALUE)) as u32) } } impl InternalImplementations for DynamicModInt { #[inline] fn mul_impl(lhs: Self, rhs: Self) -> Self { I::companion_barrett().with(|bt| Self::raw(bt.borrow().mul(lhs.val, rhs.val))) } } macro_rules! impl_basic_traits { () => {}; (impl <$generic_param:ident : $generic_param_bound:tt> _ for $self:ty; $($rest:tt)*) => { impl <$generic_param: $generic_param_bound> Default for $self { #[inline] fn default() -> Self { Self::default_impl() } } impl <$generic_param: $generic_param_bound> FromStr for $self { type Err = Infallible; #[inline] fn from_str(s: &str) -> Result { Self::from_str_impl(s) } } impl<$generic_param: $generic_param_bound, V: RemEuclidU32> From for $self { #[inline] fn from(from: V) -> Self { Self::new(from) } } #[allow(clippy::derive_hash_xor_eq)] impl<$generic_param: $generic_param_bound> Hash for $self { #[inline] fn hash(&self, state: &mut H) { Self::hash_impl(self, state) } } impl<$generic_param: $generic_param_bound> fmt::Display for $self { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Self::display_impl(self, f) } } impl<$generic_param: $generic_param_bound> fmt::Debug for $self { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Self::debug_impl(self, f) } } impl<$generic_param: $generic_param_bound> Neg for $self { type Output = $self; #[inline] fn neg(self) -> $self { Self::neg_impl(self) } } impl<$generic_param: $generic_param_bound> Neg for &'_ $self { type Output = $self; #[inline] fn neg(self) -> $self { <$self>::neg_impl(*self) } } impl_basic_traits!($($rest)*); }; } impl_basic_traits! { impl _ for StaticModInt ; impl _ for DynamicModInt; } macro_rules! impl_bin_ops { () => {}; (for<$generic_param:ident : $generic_param_bound:tt> <$lhs_ty:ty> ~ <$rhs_ty:ty> -> $output:ty { { $lhs_body:expr } ~ { $rhs_body:expr } } $($rest:tt)*) => { impl <$generic_param: $generic_param_bound> Add<$rhs_ty> for $lhs_ty { type Output = $output; #[inline] fn add(self, rhs: $rhs_ty) -> $output { <$output>::add_impl(apply($lhs_body, self), apply($rhs_body, rhs)) } } impl <$generic_param: $generic_param_bound> Sub<$rhs_ty> for $lhs_ty { type Output = $output; #[inline] fn sub(self, rhs: $rhs_ty) -> $output { <$output>::sub_impl(apply($lhs_body, self), apply($rhs_body, rhs)) } } impl <$generic_param: $generic_param_bound> Mul<$rhs_ty> for $lhs_ty { type Output = $output; #[inline] fn mul(self, rhs: $rhs_ty) -> $output { <$output>::mul_impl(apply($lhs_body, self), apply($rhs_body, rhs)) } } impl <$generic_param: $generic_param_bound> Div<$rhs_ty> for $lhs_ty { type Output = $output; #[inline] fn div(self, rhs: $rhs_ty) -> $output { <$output>::div_impl(apply($lhs_body, self), apply($rhs_body, rhs)) } } impl_bin_ops!($($rest)*); }; } macro_rules! impl_assign_ops { () => {}; (for<$generic_param:ident : $generic_param_bound:tt> <$lhs_ty:ty> ~= <$rhs_ty:ty> { _ ~= { $rhs_body:expr } } $($rest:tt)*) => { impl <$generic_param: $generic_param_bound> AddAssign<$rhs_ty> for $lhs_ty { #[inline] fn add_assign(&mut self, rhs: $rhs_ty) { *self = *self + apply($rhs_body, rhs); } } impl <$generic_param: $generic_param_bound> SubAssign<$rhs_ty> for $lhs_ty { #[inline] fn sub_assign(&mut self, rhs: $rhs_ty) { *self = *self - apply($rhs_body, rhs); } } impl <$generic_param: $generic_param_bound> MulAssign<$rhs_ty> for $lhs_ty { #[inline] fn mul_assign(&mut self, rhs: $rhs_ty) { *self = *self * apply($rhs_body, rhs); } } impl <$generic_param: $generic_param_bound> DivAssign<$rhs_ty> for $lhs_ty { #[inline] fn div_assign(&mut self, rhs: $rhs_ty) { *self = *self / apply($rhs_body, rhs); } } impl_assign_ops!($($rest)*); }; } #[inline] fn apply O, X, O>(f: F, x: X) -> O { f(x) } impl_bin_ops! { for > ~ > -> StaticModInt { { |x| x } ~ { |x| x } } for > ~ <&'_ StaticModInt > -> StaticModInt { { |x| x } ~ { |&x| x } } for <&'_ StaticModInt > ~ > -> StaticModInt { { |&x| x } ~ { |x| x } } for <&'_ StaticModInt > ~ <&'_ StaticModInt > -> StaticModInt { { |&x| x } ~ { |&x| x } } for > ~ > -> DynamicModInt { { |x| x } ~ { |x| x } } for > ~ <&'_ DynamicModInt> -> DynamicModInt { { |x| x } ~ { |&x| x } } for <&'_ DynamicModInt> ~ > -> DynamicModInt { { |&x| x } ~ { |x| x } } for <&'_ DynamicModInt> ~ <&'_ DynamicModInt> -> DynamicModInt { { |&x| x } ~ { |&x| x } } } impl_assign_ops! { for > ~= > { _ ~= { |x| x } } for > ~= <&'_ StaticModInt > { _ ~= { |&x| x } } for > ~= > { _ ~= { |x| x } } for > ~= <&'_ DynamicModInt> { _ ~= { |&x| x } } } macro_rules! impl_folding { () => {}; (impl<$generic_param:ident : $generic_param_bound:tt> $trait:ident<_> for $self:ty { fn $method:ident(_) -> _ { _($unit:expr, $op:expr) } } $($rest:tt)*) => { impl<$generic_param: $generic_param_bound> $trait for $self { #[inline] fn $method(iter: S) -> Self where S: Iterator, { iter.fold($unit, $op) } } impl<'a, $generic_param: $generic_param_bound> $trait<&'a Self> for $self { #[inline] fn $method(iter: S) -> Self where S: Iterator, { iter.fold($unit, $op) } } impl_folding!($($rest)*); }; } impl_folding! { impl Sum<_> for StaticModInt { fn sum(_) -> _ { _(Self::raw(0), Add::add) } } impl Product<_> for StaticModInt { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } } impl Sum<_> for DynamicModInt { fn sum(_) -> _ { _(Self::raw(0), Add::add) } } impl Product<_> for DynamicModInt { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } } } } use dsu::*; use global::*; use input::*; use modint::*;