diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
 
 Haskell port of [ac-library](https://github.com/atcoder/ac-library), a library for competitive programming on [AtCoder](https://atcoder.jp/).
 
+The `main` branch is the version avaiable on AtCoder. See `dev` branch for upcoming updates.
+
 ## Notes
 
 - The library is mainly for AtCoder and only GHC 9.8.4 is guaranteed to be supported.
@@ -10,5 +12,5 @@
 
 ## Usage
 
-See the API documentation for more information.
+See the [API documentation on Hackage](https://hackage.haskell.org/package/ac-library-hs) for more information.
 
diff --git a/ac-library-hs.cabal b/ac-library-hs.cabal
--- a/ac-library-hs.cabal
+++ b/ac-library-hs.cabal
@@ -4,7 +4,7 @@
 -- PVP summary:  +-+------- breaking API changes
 --               | | +----- non-breaking API additions
 --               | | | +--- code changes with no API change
-version:         1.3.0.1
+version:         1.3.1.0
 synopsis:        Data structures and algorithms
 description:
   Haskell port of [ac-library](https://github.com/atcoder/ac-library), a library for competitive
diff --git a/src/AtCoder/Extra/Monoid/RollingHash.hs b/src/AtCoder/Extra/Monoid/RollingHash.hs
--- a/src/AtCoder/Extra/Monoid/RollingHash.hs
+++ b/src/AtCoder/Extra/Monoid/RollingHash.hs
@@ -25,6 +25,7 @@
 import Data.Vector.Generic.Mutable qualified as VGM
 import Data.Vector.Unboxed qualified as VU
 import Data.Vector.Unboxed.Mutable qualified as VUM
+import Data.WideWord.Word128
 import GHC.Exts (proxy#)
 import GHC.TypeNats (KnownNat, natVal')
 
@@ -34,7 +35,6 @@
 -- Combining `RollingHash` with `SegTree` enables \(O(\log |s|)\) string slice creation and
 -- \(O(1)\) slice comparison.
 --
---
 -- ==== __Example__
 -- It's convenient to define a type alias of `RollingHash`:
 --
@@ -42,7 +42,7 @@
 -- >>> import AtCoder.SegTree qualified as ST
 -- >>> import Data.Char (ord)
 -- >>> import Data.Semigroup (Dual (..))
--- >>> type RH = RH.RollingHash 100 998244353
+-- >>> type RH = RH.RollingHash 100 2305843009213693951
 --
 -- Let's test whether "abcba" is a palindrome:
 --
@@ -76,7 +76,7 @@
 -- @since 1.1.0.0
 {-# INLINE new #-}
 new :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
-new h = RollingHash (h `mod` fromIntegral (natVal' (proxy# @p))) (fromIntegral (natVal' (proxy# @b)))
+new h = RollingHash (h `rem` fromIntegral (natVal' (proxy# @p))) (fromIntegral (natVal' (proxy# @b)))
 
 -- | \(O(1)\) Creates a one-length `RollingHash` from an integer without taking the mod.
 --
@@ -85,15 +85,32 @@
 unsafeNew :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
 unsafeNew h = RollingHash h (fromIntegral (natVal' (proxy# @b)))
 
+-- | \(O(1)\)
+{-# INLINE calc #-}
+calc :: forall b p. (KnownNat b, KnownNat p) => RollingHash b p -> RollingHash b p -> RollingHash b p
+calc (RollingHash !digit1 !hash1) (RollingHash !digit2 !hash2)
+  | p < 3037000499 =
+      let !digit' = digit1 * digit2 `rem` p
+          !hash' = addMod p (hash1 * digit2 `rem` p) hash2
+       in RollingHash digit' hash'
+  | otherwise =
+      -- TODO: This is slow
+      let !digit' = fromIntegral $! to128 digit1 * to128 digit2 `rem` to128 p
+          !hash' = fromIntegral $! (to128 hash1 * to128 digit2 + to128 hash2) `rem` to128 p
+       in RollingHash digit' hash'
+  where
+    !p = fromIntegral $ natVal' (proxy# @p)
+    to128 :: Int -> Word128
+    to128 = fromIntegral
+    addMod :: Int -> Int -> Int -> Int
+    addMod m x y
+      | x + y >= m = x + y - m
+      | otherwise = x + y
+
 -- | @since 1.1.0.0
 instance (KnownNat b, KnownNat p) => Semigroup (RollingHash b p) where
-  -- \| \(O(1)\)
   {-# INLINE (<>) #-}
-  (RollingHash !digit1 !hash1) <> (RollingHash !digit2 !hash2) = RollingHash digit' hash'
-    where
-      !p = fromIntegral $ natVal' (proxy# @p)
-      !digit' = digit1 * digit2 `mod` p
-      !hash' = (hash1 * digit2 + hash2) `mod` p
+  (<>) = calc
 
 -- | @since 1.1.0.0
 instance (KnownNat b, KnownNat p) => Monoid (RollingHash b p) where
diff --git a/test/Tests/Extra/Monoid.hs b/test/Tests/Extra/Monoid.hs
--- a/test/Tests/Extra/Monoid.hs
+++ b/test/Tests/Extra/Monoid.hs
@@ -100,6 +100,13 @@
     pure $ RollingHash hash next
 
 -- orphan instance
+instance QC.Arbitrary (RollingHash b 2305843009213693951) where
+  arbitrary = do
+    hash <- QC.chooseInt (0, 2305843009213693951 - 1)
+    next <- QC.chooseInt (0, 2305843009213693951 - 1)
+    pure $ RollingHash hash next
+
+-- orphan instance
 instance QC.Arbitrary (Max Int) where
   arbitrary = Max <$> QC.arbitrary
 
@@ -249,6 +256,14 @@
     testGroup
       "RollingHash"
       [ laws @(RollingHash 100 998244353)
+          [ QCC.semigroupLaws,
+            QCC.monoidLaws,
+            QCC.semigroupMonoidLaws
+          ]
+      ],
+    testGroup
+      "RollingHash"
+      [ laws @(RollingHash 100 2305843009213693951)
           [ QCC.semigroupLaws,
             QCC.monoidLaws,
             QCC.semigroupMonoidLaws
