diff --git a/src/internal_type_traits.rs b/src/internal_type_traits.rs
index 88a52a9..4405c9b 100644
--- a/src/internal_type_traits.rs
+++ b/src/internal_type_traits.rs
@@ -1,6 +1,6 @@
 use std::{
     fmt,
-    iter::{Product, Sum},
+    iter::{self, Product, Sum},
     ops::{
         Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
         DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
@@ -52,25 +52,33 @@ pub trait Integral:
     + fmt::Debug
     + fmt::Binary
     + fmt::Octal
-    + Zero
-    + One
     + BoundedBelow
     + BoundedAbove
 {
 }
 
 /// Class that has additive identity element
-pub trait Zero {
+pub(super) trait SumExt: Sum {
     /// The additive identity element
-    fn zero() -> Self;
+    #[inline]
+    fn zero() -> Self {
+        iter::empty().sum()
+    }
 }
 
+impl<T: Sum> SumExt for T {}
+
 /// Class that has multiplicative identity element
-pub trait One {
+pub(super) trait ProductExt: Product {
     /// The multiplicative identity element
-    fn one() -> Self;
+    #[inline]
+    fn one() -> Self {
+        iter::empty().product()
+    }
 }
 
+impl<T: Product> ProductExt for T {}
+
 pub trait BoundedBelow {
     fn min_value() -> Self;
 }
@@ -82,20 +90,6 @@ pub trait BoundedAbove {
 macro_rules! impl_integral {
     ($($ty:ty),*) => {
         $(
-            impl Zero for $ty {
-                #[inline]
-                fn zero() -> Self {
-                    0
-                }
-            }
-
-            impl One for $ty {
-                #[inline]
-                fn one() -> Self {
-                    1
-                }
-            }
-
             impl BoundedBelow for $ty {
                 #[inline]
                 fn min_value() -> Self {
@@ -116,3 +110,40 @@ macro_rules! impl_integral {
 }
 
 impl_integral!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
+
+#[cfg(test)]
+mod tests {
+    use super::{ProductExt as _, SumExt as _};
+
+    #[test]
+    fn zero() {
+        assert_eq!(0, i8::zero());
+        assert_eq!(0, i16::zero());
+        assert_eq!(0, i32::zero());
+        assert_eq!(0, i64::zero());
+        assert_eq!(0, i128::zero());
+        assert_eq!(0, isize::zero());
+        assert_eq!(0, u8::zero());
+        assert_eq!(0, u16::zero());
+        assert_eq!(0, u32::zero());
+        assert_eq!(0, u64::zero());
+        assert_eq!(0, u128::zero());
+        assert_eq!(0, usize::zero());
+    }
+
+    #[test]
+    fn one() {
+        assert_eq!(1, i8::one());
+        assert_eq!(1, i16::one());
+        assert_eq!(1, i32::one());
+        assert_eq!(1, i64::one());
+        assert_eq!(1, i128::one());
+        assert_eq!(1, isize::one());
+        assert_eq!(1, u8::one());
+        assert_eq!(1, u16::one());
+        assert_eq!(1, u32::one());
+        assert_eq!(1, u64::one());
+        assert_eq!(1, u128::one());
+        assert_eq!(1, usize::one());
+    }
+}
diff --git a/src/maxflow.rs b/src/maxflow.rs
index 6e6e157..4459171 100644
--- a/src/maxflow.rs
+++ b/src/maxflow.rs
@@ -1,6 +1,6 @@
 #![allow(dead_code)]
 use crate::internal_queue::SimpleQueue;
-use crate::internal_type_traits::Integral;
+use crate::internal_type_traits::{Integral, SumExt as _};
 use std::cmp::min;
 use std::iter;
 
diff --git a/src/mincostflow.rs b/src/mincostflow.rs
index 7d708e4..5eb6bf9 100644
--- a/src/mincostflow.rs
+++ b/src/mincostflow.rs
@@ -1,4 +1,4 @@
-use crate::internal_type_traits::Integral;
+use crate::internal_type_traits::{Integral, SumExt as _};
 
 pub struct MinCostFlowEdge<T> {
     pub from: usize,
diff --git a/src/segtree.rs b/src/segtree.rs
index b543aa3..9f9dbab 100644
--- a/src/segtree.rs
+++ b/src/segtree.rs
@@ -1,7 +1,8 @@
 use crate::internal_bit::ceil_pow2;
-use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
+use crate::internal_type_traits::{BoundedAbove, BoundedBelow, ProductExt as _, SumExt as _};
 use std::cmp::{max, min};
 use std::convert::Infallible;
+use std::iter::{Product, Sum};
 use std::marker::PhantomData;
 use std::ops::{Add, Mul};
 
@@ -43,7 +44,7 @@ where
 pub struct Additive<S>(Infallible, PhantomData<fn() -> S>);
 impl<S> Monoid for Additive<S>
 where
-    S: Copy + Add<Output = S> + Zero,
+    S: Copy + Add<Output = S> + Sum,
 {
     type S = S;
     fn identity() -> Self::S {
@@ -57,7 +58,7 @@ where
 pub struct Multiplicative<S>(Infallible, PhantomData<fn() -> S>);
 impl<S> Monoid for Multiplicative<S>
 where
-    S: Copy + Mul<Output = S> + One,
+    S: Copy + Mul<Output = S> + Product,
 {
     type S = S;
     fn identity() -> Self::S {