diff --git a/.cargo/config.toml b/.cargo/config.toml
deleted file mode 100644
index 3d99f63..0000000
--- a/.cargo/config.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[build]
-# This works both on local `cargo doc` and on docs.rs because we don't have any `normal` dependency.
-# In most cases, `package.metadata.docs.rs` is recommended.
-#
-# See also:
-# - https://docs.rs/rustdoc-katex-demo
-# - https://docs.rs/rust-latex-doc-minimal-example
-rustdocflags = ["--html-in-header", "./doc/katex-header.html"]
diff --git a/.gitignore b/.gitignore
index 96ef6c0..4531c3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-/target
+**/target/
 Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
index 5348943..cea2975 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,3 +1,5 @@
+[workspace]
+
 [package]
 name = "ac-library-rs"
 version = "0.1.0"
@@ -10,10 +12,21 @@ keywords = ["competitive"]
 categories = ["algorithms", "data-structures"]
 publish = false
 
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-
-[dev-dependencies]
-proconio = "=0.3.6"
-rand = "0.7.3"
+__acl_convolution = { package = "acl_convolution", version = "0.1.0", path = "./acl_convolution" }
+__acl_dsu         = { package = "acl_dsu"        , version = "0.1.0", path = "./acl_dsu"         }
+__acl_fenwicktree = { package = "acl_fenwicktree", version = "0.1.0", path = "./acl_fenwicktree" }
+__acl_lazysegtree = { package = "acl_lazysegtree", version = "0.1.0", path = "./acl_lazysegtree" }
+__acl_math        = { package = "acl_math"       , version = "0.1.0", path = "./acl_math"        }
+__acl_maxflow     = { package = "acl_maxflow"    , version = "0.1.0", path = "./acl_maxflow"     }
+__acl_mincostflow = { package = "acl_mincostflow", version = "0.1.0", path = "./acl_mincostflow" }
+__acl_modint      = { package = "acl_modint"     , version = "0.1.0", path = "./acl_modint"      }
+__acl_scc         = { package = "acl_scc"        , version = "0.1.0", path = "./acl_scc"         }
+__acl_segtree     = { package = "acl_segtree"    , version = "0.1.0", path = "./acl_segtree"     }
+__acl_string      = { package = "acl_string"     , version = "0.1.0", path = "./acl_string"      }
+__acl_twosat      = { package = "acl_twosat"     , version = "0.1.0", path = "./acl_twosat"      }
diff --git a/acl_convolution/Cargo.toml b/acl_convolution/Cargo.toml
new file mode 100644
index 0000000..a9110a4
--- /dev/null
+++ b/acl_convolution/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "acl_convolution"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_bit = { package = "acl_internal_bit", version = "0.1.0", path = "../acl_internal_bit" }
+__acl_internal_math = { package = "acl_internal_math", version = "0.1.0", path = "../acl_internal_math" }
+__acl_modint = { package = "acl_modint", version = "0.1.0", path = "../acl_modint" }
+
+[dev-dependencies]
+rand = "0.7.3"
diff --git a/doc/katex-header.html b/acl_convolution/katex-header.html
similarity index 100%
rename from doc/katex-header.html
rename to acl_convolution/katex-header.html
diff --git a/src/convolution.rs b/acl_convolution/src/lib.rs
similarity index 96%
rename from src/convolution.rs
rename to acl_convolution/src/lib.rs
index 9576e3e..a76af21 100644
--- a/src/convolution.rs
+++ b/acl_convolution/src/lib.rs
@@ -8,9 +8,9 @@ macro_rules! modulus {
                 const VALUE: u32 = $name as _;
                 const HINT_VALUE_IS_PRIME: bool = true;
 
-                fn butterfly_cache() -> &'static ::std::thread::LocalKey<::std::cell::RefCell<::std::option::Option<crate::modint::ButterflyCache<Self>>>> {
+                fn butterfly_cache() -> &'static ::std::thread::LocalKey<::std::cell::RefCell<::std::option::Option<self::modint::ButterflyCache<Self>>>> {
                     thread_local! {
-                        static BUTTERFLY_CACHE: ::std::cell::RefCell<::std::option::Option<crate::modint::ButterflyCache<$name>>> = ::std::default::Default::default();
+                        static BUTTERFLY_CACHE: ::std::cell::RefCell<::std::option::Option<self::modint::ButterflyCache<$name>>> = ::std::default::Default::default();
                     }
                     &BUTTERFLY_CACHE
                 }
@@ -19,10 +19,11 @@ macro_rules! modulus {
     };
 }
 
-use crate::{
-    internal_bit, internal_math,
-    modint::{ButterflyCache, Modulus, RemEuclidU32, StaticModInt},
-};
+extern crate __acl_internal_bit as internal_bit;
+extern crate __acl_internal_math as internal_math;
+extern crate __acl_modint as modint;
+
+use self::modint::{ButterflyCache, Modulus, RemEuclidU32, StaticModInt};
 use std::{
     cmp,
     convert::{TryFrom, TryInto as _},
@@ -232,10 +233,7 @@ fn prepare<M: Modulus>() -> ButterflyCache<M> {
 
 #[cfg(test)]
 mod tests {
-    use crate::{
-        modint::{Mod998244353, Modulus, StaticModInt},
-        RemEuclidU32,
-    };
+    use super::modint::{self, Mod998244353, Modulus, RemEuclidU32, StaticModInt};
     use rand::{rngs::ThreadRng, Rng as _};
     use std::{
         convert::{TryFrom, TryInto as _},
diff --git a/acl_dsu/Cargo.toml b/acl_dsu/Cargo.toml
new file mode 100644
index 0000000..ebe4546
--- /dev/null
+++ b/acl_dsu/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_dsu"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_dsu/katex-header.html b/acl_dsu/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_dsu/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/dsu.rs b/acl_dsu/src/lib.rs
similarity index 100%
rename from src/dsu.rs
rename to acl_dsu/src/lib.rs
diff --git a/acl_fenwicktree/Cargo.toml b/acl_fenwicktree/Cargo.toml
new file mode 100644
index 0000000..e569950
--- /dev/null
+++ b/acl_fenwicktree/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_fenwicktree"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_fenwicktree/katex-header.html b/acl_fenwicktree/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_fenwicktree/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/fenwicktree.rs b/acl_fenwicktree/src/lib.rs
similarity index 100%
rename from src/fenwicktree.rs
rename to acl_fenwicktree/src/lib.rs
diff --git a/acl_internal_bit/Cargo.toml b/acl_internal_bit/Cargo.toml
new file mode 100644
index 0000000..a76f31b
--- /dev/null
+++ b/acl_internal_bit/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_internal_bit"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_internal_bit/katex-header.html b/acl_internal_bit/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_internal_bit/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/internal_bit.rs b/acl_internal_bit/src/lib.rs
similarity index 95%
rename from src/internal_bit.rs
rename to acl_internal_bit/src/lib.rs
index 5ab7583..1ba7a83 100644
--- a/src/internal_bit.rs
+++ b/acl_internal_bit/src/lib.rs
@@ -3,7 +3,7 @@
 // - `bsf` = `__builtin_ctz`: is equivalent to `{integer}::trailing_zeros`
 
 #[allow(dead_code)]
-pub(crate) fn ceil_pow2(n: u32) -> u32 {
+pub fn ceil_pow2(n: u32) -> u32 {
     32 - n.saturating_sub(1).leading_zeros()
 }
 
diff --git a/acl_internal_math/Cargo.toml b/acl_internal_math/Cargo.toml
new file mode 100644
index 0000000..8cb72ab
--- /dev/null
+++ b/acl_internal_math/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_internal_math"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_internal_math/katex-header.html b/acl_internal_math/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_internal_math/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/internal_math.rs b/acl_internal_math/src/lib.rs
similarity index 95%
rename from src/internal_math.rs
rename to acl_internal_math/src/lib.rs
index 515191c..9b900d8 100644
--- a/src/internal_math.rs
+++ b/acl_internal_math/src/lib.rs
@@ -8,7 +8,7 @@ use std::mem::swap;
 /// # Returns
 /// x mod m
 /* const */
-pub(crate) fn safe_mod(mut x: i64, m: i64) -> i64 {
+pub fn safe_mod(mut x: i64, m: i64) -> i64 {
     x %= m;
     if x < 0 {
         x += m;
@@ -19,9 +19,9 @@ pub(crate) fn safe_mod(mut x: i64, m: i64) -> i64 {
 /// Fast modular by barrett reduction
 /// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
 /// NOTE: reconsider after Ice Lake
-pub(crate) struct Barrett {
-    pub(crate) _m: u32,
-    pub(crate) im: u64,
+pub struct Barrett {
+    pub _m: u32,
+    pub im: u64,
 }
 
 impl Barrett {
@@ -30,7 +30,7 @@ impl Barrett {
     /// (Note: `m <= 2^31` should also hold, which is undocumented in the original library.
     /// See the [pull reqeust commment](https://github.com/rust-lang-ja/ac-library-rs/pull/3#discussion_r484661007)
     /// for more details.)
-    pub(crate) fn new(m: u32) -> Barrett {
+    pub fn new(m: u32) -> Barrett {
         Barrett {
             _m: m,
             im: (-1i64 as u64 / m as u64).wrapping_add(1),
@@ -39,7 +39,7 @@ impl Barrett {
 
     /// # Returns
     /// `m`
-    pub(crate) fn umod(&self) -> u32 {
+    pub fn umod(&self) -> u32 {
         self._m
     }
 
@@ -50,7 +50,7 @@ impl Barrett {
     /// # Returns
     /// a * b % m
     #[allow(clippy::many_single_char_names)]
-    pub(crate) fn mul(&self, a: u32, b: u32) -> u32 {
+    pub fn mul(&self, a: u32, b: u32) -> u32 {
         mul_mod(a, b, self._m, self.im)
     }
 }
@@ -62,7 +62,7 @@ impl Barrett {
 /// * `m` `1 <= m <= 2^31`
 /// * `im` = ceil(2^64 / `m`)
 #[allow(clippy::many_single_char_names)]
-pub(crate) fn mul_mod(a: u32, b: u32, m: u32, im: u64) -> u32 {
+pub fn mul_mod(a: u32, b: u32, m: u32, im: u64) -> u32 {
     // [1] m = 1
     // a = b = im = 0, so okay
 
@@ -91,7 +91,7 @@ pub(crate) fn mul_mod(a: u32, b: u32, m: u32, im: u64) -> u32 {
 /// `(x ** n) % m`
 /* const */
 #[allow(clippy::many_single_char_names)]
-pub(crate) fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 {
+pub fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 {
     if m == 1 {
         return 0;
     }
@@ -115,7 +115,7 @@ pub(crate) fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 {
 /// # Parameters
 /// * `n` `0 <= n`
 /* const */
-pub(crate) fn is_prime(n: i32) -> bool {
+pub fn is_prime(n: i32) -> bool {
     let n = n as i64;
     match n {
         _ if n <= 1 => return false,
@@ -151,7 +151,7 @@ pub(crate) fn is_prime(n: i32) -> bool {
 /// (g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
 /* const */
 #[allow(clippy::many_single_char_names)]
-pub(crate) fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
+pub fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
     let a = safe_mod(a, b);
     if a == 0 {
         return (b, 0);
@@ -191,7 +191,7 @@ pub(crate) fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
 /// @param m must be prime
 /// @return primitive root (and minimum in now)
 /* const */
-pub(crate) fn primitive_root(m: i32) -> i32 {
+pub fn primitive_root(m: i32) -> i32 {
     match m {
         2 => return 1,
         167_772_161 => return 3,
@@ -239,7 +239,7 @@ pub(crate) fn primitive_root(m: i32) -> i32 {
 mod tests {
     #![allow(clippy::unreadable_literal)]
     #![allow(clippy::cognitive_complexity)]
-    use crate::internal_math::{inv_gcd, is_prime, pow_mod, primitive_root, safe_mod, Barrett};
+    use super::{inv_gcd, is_prime, pow_mod, primitive_root, safe_mod, Barrett};
     use std::collections::HashSet;
 
     #[test]
diff --git a/acl_internal_queue/Cargo.toml b/acl_internal_queue/Cargo.toml
new file mode 100644
index 0000000..fb61964
--- /dev/null
+++ b/acl_internal_queue/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_internal_queue"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_internal_queue/katex-header.html b/acl_internal_queue/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_internal_queue/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/internal_queue.rs b/acl_internal_queue/src/lib.rs
similarity index 84%
rename from src/internal_queue.rs
rename to acl_internal_queue/src/lib.rs
index 5e51e9a..ca4b782 100644
--- a/src/internal_queue.rs
+++ b/acl_internal_queue/src/lib.rs
@@ -1,32 +1,32 @@
 #![allow(dead_code)]
 
 #[derive(Default)]
-pub(crate) struct SimpleQueue<T> {
+pub struct SimpleQueue<T> {
     payload: Vec<T>,
     pos: usize,
 }
 
 impl<T> SimpleQueue<T> {
-    pub(crate) fn reserve(&mut self, n: usize) {
+    pub fn reserve(&mut self, n: usize) {
         if n > self.payload.len() {
             self.payload.reserve(n - self.payload.len());
         }
     }
 
-    pub(crate) fn size(&self) -> usize {
+    pub fn size(&self) -> usize {
         self.payload.len() - self.pos
     }
 
-    pub(crate) fn empty(&self) -> bool {
+    pub fn empty(&self) -> bool {
         self.pos == self.payload.len()
     }
 
-    pub(crate) fn push(&mut self, t: T) {
+    pub fn push(&mut self, t: T) {
         self.payload.push(t);
     }
 
     // Do we need mutable version?
-    pub(crate) fn front(&self) -> Option<&T> {
+    pub fn front(&self) -> Option<&T> {
         if self.pos < self.payload.len() {
             Some(&self.payload[self.pos])
         } else {
@@ -34,12 +34,12 @@ impl<T> SimpleQueue<T> {
         }
     }
 
-    pub(crate) fn clear(&mut self) {
+    pub fn clear(&mut self) {
         self.payload.clear();
         self.pos = 0;
     }
 
-    pub(crate) fn pop(&mut self) -> Option<&T> {
+    pub fn pop(&mut self) -> Option<&T> {
         if self.pos < self.payload.len() {
             self.pos += 1;
             Some(&self.payload[self.pos - 1])
@@ -51,7 +51,7 @@ impl<T> SimpleQueue<T> {
 
 #[cfg(test)]
 mod test {
-    use crate::internal_queue::SimpleQueue;
+    use super::SimpleQueue;
 
     #[allow(clippy::cognitive_complexity)]
     #[test]
diff --git a/acl_internal_scc/Cargo.toml b/acl_internal_scc/Cargo.toml
new file mode 100644
index 0000000..2205eb5
--- /dev/null
+++ b/acl_internal_scc/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_internal_scc"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_internal_scc/katex-header.html b/acl_internal_scc/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_internal_scc/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/internal_scc.rs b/acl_internal_scc/src/lib.rs
similarity index 100%
rename from src/internal_scc.rs
rename to acl_internal_scc/src/lib.rs
diff --git a/acl_internal_type_traits/Cargo.toml b/acl_internal_type_traits/Cargo.toml
new file mode 100644
index 0000000..d0a0240
--- /dev/null
+++ b/acl_internal_type_traits/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_internal_type_traits"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_internal_type_traits/katex-header.html b/acl_internal_type_traits/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_internal_type_traits/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/internal_type_traits.rs b/acl_internal_type_traits/src/lib.rs
similarity index 100%
rename from src/internal_type_traits.rs
rename to acl_internal_type_traits/src/lib.rs
diff --git a/acl_lazysegtree/Cargo.toml b/acl_lazysegtree/Cargo.toml
new file mode 100644
index 0000000..95d7536
--- /dev/null
+++ b/acl_lazysegtree/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "acl_lazysegtree"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_bit = { package = "acl_internal_bit", version = "0.1.0", path = "../acl_internal_bit" }
+__acl_segtree = { package = "acl_segtree", version = "0.1.0", path = "../acl_segtree" }
diff --git a/acl_lazysegtree/katex-header.html b/acl_lazysegtree/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_lazysegtree/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/lazysegtree.rs b/acl_lazysegtree/src/lib.rs
similarity index 98%
rename from src/lazysegtree.rs
rename to acl_lazysegtree/src/lib.rs
index 47020a8..6a1e90f 100644
--- a/src/lazysegtree.rs
+++ b/acl_lazysegtree/src/lib.rs
@@ -1,5 +1,7 @@
-use crate::internal_bit::ceil_pow2;
-use crate::Monoid;
+extern crate __acl_internal_bit as internal_bit;
+extern crate __acl_segtree as segtree;
+
+use self::{internal_bit::ceil_pow2, segtree::Monoid};
 
 pub trait MapMonoid {
     type M: Monoid;
@@ -314,7 +316,7 @@ where
 
 #[cfg(test)]
 mod tests {
-    use crate::{LazySegtree, MapMonoid, Max};
+    use super::{segtree::Max, LazySegtree, MapMonoid};
 
     struct MaxAdd;
     impl MapMonoid for MaxAdd {
diff --git a/acl_math/Cargo.toml b/acl_math/Cargo.toml
new file mode 100644
index 0000000..ccf83db
--- /dev/null
+++ b/acl_math/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "acl_math"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_math = { package = "acl_internal_math", version = "0.1.0", path = "../acl_internal_math" }
+
+[dev-dependencies]
+ac-library-rs = { version = "*", path = ".." }
diff --git a/acl_math/katex-header.html b/acl_math/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_math/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/math.rs b/acl_math/src/lib.rs
similarity index 99%
rename from src/math.rs
rename to acl_math/src/lib.rs
index 61f15d5..d6a6aba 100644
--- a/src/math.rs
+++ b/acl_math/src/lib.rs
@@ -1,6 +1,6 @@
 //! Number-theoretic algorithms.
 
-use crate::internal_math;
+extern crate __acl_internal_math as internal_math;
 
 use std::mem::swap;
 
diff --git a/acl_maxflow/Cargo.toml b/acl_maxflow/Cargo.toml
new file mode 100644
index 0000000..30e8b5d
--- /dev/null
+++ b/acl_maxflow/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "acl_maxflow"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_queue = { package = "acl_internal_queue", version = "0.1.0", path = "../acl_internal_queue" }
+__acl_internal_type_traits = { package = "acl_internal_type_traits", version = "0.1.0", path = "../acl_internal_type_traits" }
diff --git a/acl_maxflow/katex-header.html b/acl_maxflow/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_maxflow/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/maxflow.rs b/acl_maxflow/src/lib.rs
similarity index 97%
rename from src/maxflow.rs
rename to acl_maxflow/src/lib.rs
index 93b337c..4302a24 100644
--- a/src/maxflow.rs
+++ b/acl_maxflow/src/lib.rs
@@ -1,6 +1,9 @@
 #![allow(dead_code)]
-use crate::internal_queue::SimpleQueue;
-use crate::internal_type_traits::Integral;
+
+extern crate __acl_internal_queue as internal_queue;
+extern crate __acl_internal_type_traits as internal_type_traits;
+
+use self::{internal_queue::SimpleQueue, internal_type_traits::Integral};
 use std::cmp::min;
 use std::iter;
 
@@ -224,7 +227,7 @@ struct _Edge<Cap> {
 
 #[cfg(test)]
 mod test {
-    use crate::{Edge, MfGraph};
+    use super::{Edge, MfGraph};
 
     #[test]
     fn test_max_flow_wikipedia() {
diff --git a/acl_mincostflow/Cargo.toml b/acl_mincostflow/Cargo.toml
new file mode 100644
index 0000000..674eeb4
--- /dev/null
+++ b/acl_mincostflow/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "acl_mincostflow"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_type_traits = { package = "acl_internal_type_traits", version = "0.1.0", path = "../acl_internal_type_traits" }
diff --git a/acl_mincostflow/katex-header.html b/acl_mincostflow/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_mincostflow/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/mincostflow.rs b/acl_mincostflow/src/lib.rs
similarity index 98%
rename from src/mincostflow.rs
rename to acl_mincostflow/src/lib.rs
index 158a9e8..ba7de6a 100644
--- a/src/mincostflow.rs
+++ b/acl_mincostflow/src/lib.rs
@@ -1,4 +1,6 @@
-use crate::internal_type_traits::Integral;
+extern crate __acl_internal_type_traits as internal_type_traits;
+
+use self::internal_type_traits::Integral;
 
 pub struct MinCostFlowEdge<T> {
     pub from: usize,
diff --git a/acl_modint/Cargo.toml b/acl_modint/Cargo.toml
new file mode 100644
index 0000000..ae159c0
--- /dev/null
+++ b/acl_modint/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "acl_modint"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_math = { package = "acl_internal_math", version = "0.1.0", path = "../acl_internal_math" }
+
+[dev-dependencies]
+ac-library-rs = { version = "*", path = ".." }
+proconio = "=0.3.6"
diff --git a/acl_modint/katex-header.html b/acl_modint/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_modint/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/modint.rs b/acl_modint/src/lib.rs
similarity index 99%
rename from src/modint.rs
rename to acl_modint/src/lib.rs
index 8aa5220..cb09c51 100644
--- a/src/modint.rs
+++ b/acl_modint/src/lib.rs
@@ -48,7 +48,8 @@
 //! [`ModInt998244353`]: ./type.ModInt998244353.html
 //! [`ModInt`]: ./type.ModInt.html
 
-use crate::internal_math;
+extern crate __acl_internal_math as internal_math;
+
 use std::{
     cell::RefCell,
     convert::{Infallible, TryInto as _},
@@ -283,8 +284,8 @@ impl Modulus for Mod998244353 {
 
 /// Cache for butterfly operations.
 pub struct ButterflyCache<M> {
-    pub(crate) sum_e: Vec<StaticModInt<M>>,
-    pub(crate) sum_ie: Vec<StaticModInt<M>>,
+    pub sum_e: Vec<StaticModInt<M>>,
+    pub sum_ie: Vec<StaticModInt<M>>,
 }
 
 /// Represents _ℤ/mℤ_ where _m_ is a dynamic value.
@@ -1050,7 +1051,7 @@ impl_folding! {
 
 #[cfg(test)]
 mod tests {
-    use crate::modint::ModInt1000000007;
+    use super::ModInt1000000007;
 
     #[test]
     fn static_modint_new() {
diff --git a/acl_scc/Cargo.toml b/acl_scc/Cargo.toml
new file mode 100644
index 0000000..bac6351
--- /dev/null
+++ b/acl_scc/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "acl_scc"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_scc = { package = "acl_internal_scc", version = "0.1.0", path = "../acl_internal_scc" }
diff --git a/acl_scc/katex-header.html b/acl_scc/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_scc/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/scc.rs b/acl_scc/src/lib.rs
similarity index 96%
rename from src/scc.rs
rename to acl_scc/src/lib.rs
index 2eff835..645cf5b 100644
--- a/src/scc.rs
+++ b/acl_scc/src/lib.rs
@@ -1,4 +1,4 @@
-use crate::internal_scc;
+extern crate __acl_internal_scc as internal_scc;
 
 pub struct SccGraph {
     internal: internal_scc::SccGraph,
diff --git a/acl_segtree/Cargo.toml b/acl_segtree/Cargo.toml
new file mode 100644
index 0000000..717bbbc
--- /dev/null
+++ b/acl_segtree/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "acl_segtree"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_bit = { package = "acl_internal_bit", version = "0.1.0", path = "../acl_internal_bit" }
+__acl_internal_type_traits = { package = "acl_internal_type_traits", version = "0.1.0", path = "../acl_internal_type_traits" }
diff --git a/acl_segtree/katex-header.html b/acl_segtree/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_segtree/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/segtree.rs b/acl_segtree/src/lib.rs
similarity index 96%
rename from src/segtree.rs
rename to acl_segtree/src/lib.rs
index b543aa3..a103707 100644
--- a/src/segtree.rs
+++ b/acl_segtree/src/lib.rs
@@ -1,5 +1,8 @@
-use crate::internal_bit::ceil_pow2;
-use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
+extern crate __acl_internal_bit as internal_bit;
+extern crate __acl_internal_type_traits as internal_type_traits;
+
+use self::internal_bit::ceil_pow2;
+use self::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
 use std::cmp::{max, min};
 use std::convert::Infallible;
 use std::marker::PhantomData;
@@ -238,8 +241,7 @@ where
 
 #[cfg(test)]
 mod tests {
-    use crate::segtree::Max;
-    use crate::Segtree;
+    use super::{Max, Segtree};
 
     #[test]
     fn test_max_segtree() {
diff --git a/acl_string/Cargo.toml b/acl_string/Cargo.toml
new file mode 100644
index 0000000..0ff1fd5
--- /dev/null
+++ b/acl_string/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "acl_string"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
diff --git a/acl_string/katex-header.html b/acl_string/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_string/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/string.rs b/acl_string/src/lib.rs
similarity index 100%
rename from src/string.rs
rename to acl_string/src/lib.rs
diff --git a/acl_twosat/Cargo.toml b/acl_twosat/Cargo.toml
new file mode 100644
index 0000000..90c0a36
--- /dev/null
+++ b/acl_twosat/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "acl_twosat"
+version = "0.1.0"
+authors = ["rust-lang-ja Developers"]
+edition = "2018"
+description = "A Rust port of AtCoder Library (ACL)."
+license = "CC0-1.0"
+repository = "https://github.com/rust-lang-ja/ac-library-rs"
+keywords = ["competitive"]
+categories = ["algorithms", "data-structures"]
+publish = false
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--html-in-header", "./katex-header.html"]
+
+[dependencies]
+__acl_internal_scc = { package = "acl_internal_scc", version = "0.1.0", path = "../acl_internal_scc" }
diff --git a/acl_twosat/katex-header.html b/acl_twosat/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/acl_twosat/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/twosat.rs b/acl_twosat/src/lib.rs
similarity index 98%
rename from src/twosat.rs
rename to acl_twosat/src/lib.rs
index ac5f8b6..3f5e1e1 100644
--- a/src/twosat.rs
+++ b/acl_twosat/src/lib.rs
@@ -1,4 +1,4 @@
-use crate::internal_scc;
+extern crate __acl_internal_scc as internal_scc;
 
 pub struct TwoSat {
     n: usize,
diff --git a/expand.py b/expand.py
index 4072ced..b1bf08d 100755
--- a/expand.py
+++ b/expand.py
@@ -4,6 +4,7 @@
 import getopt
 import tempfile
 import subprocess
+import re
 
 usage = '''Usage:expand.py [options] <output modules>
 Output Modules:
@@ -43,18 +44,25 @@
                    'scc': ('internal_scc',),
                    'segtree': ('internal_bit', 'internal_type_traits',),
                    'twosat': ('internal_scc',), }
-src_path = 'src/'
+EXTERN_CRATE_PATTERN = re.compile(
+    'extern crate [a-z0-9_].* as (?P<name>[a-z0-9_]+);'
+)
 
 
-def output_file(filename):
-    global src_path
-
+def output_file(name):
     res = []
-    with open(src_path+filename+'.rs', 'r') as f:
-        res.append('pub mod {} {{'.format(filename))
+    with open('./acl_{}/src/lib.rs'.format(name), 'r') as f:
+        res.append('pub mod acl_{} {{'.format(name))
 
         for line in f:
-            res.append(line.rstrip())
+            line = line.rstrip()
+            match = EXTERN_CRATE_PATTERN.match(line)
+            if match:
+                res.append('/*{line}*/use crate::acl_{name} as {name};'.format(
+                    line=line, name=match['name'],
+                ))
+            else:
+                res.append(line)
 
         res.append('}')
     return res
@@ -103,7 +111,7 @@ def output_file(filename):
     # Modules that begin with 'internal' are for internal use, so they are not
     # declared.
     if not i.startswith('internal'):
-        output_data.append('use {}::*;'.format(i))
+        output_data.append('use acl_{}::*;'.format(i))
 
 # rustfmt
 with tempfile.TemporaryDirectory() as temp_dir:
diff --git a/katex-header.html b/katex-header.html
new file mode 100644
index 0000000..0837616
--- /dev/null
+++ b/katex-header.html
@@ -0,0 +1,15 @@
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"></script>
+<script>
+  document.addEventListener("DOMContentLoaded", () => {
+    renderMathInElement(document.body, {
+      delimiters: [
+        {left: "$$", right: "$$", display: true},
+        {left: "\\[", right: "\\]", display: true},
+        {left: "$", right: "$", display: false},
+        {left: "\\(", right: "\\)", display: false}
+      ],
+    })
+  });
+</script>
diff --git a/src/lib.rs b/src/lib.rs
index 5452b25..1b53fb0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,21 +1,21 @@
-pub mod convolution;
-pub mod dsu;
-pub mod fenwicktree;
-pub mod lazysegtree;
-pub mod math;
-pub mod maxflow;
-pub mod mincostflow;
-pub mod modint;
-pub mod scc;
-pub mod segtree;
-pub mod string;
-pub mod twosat;
+pub extern crate __acl_convolution as convolution;
+pub extern crate __acl_dsu as dsu;
+pub extern crate __acl_fenwicktree as fenwicktree;
+pub extern crate __acl_lazysegtree as lazysegtree;
+pub extern crate __acl_math as math;
+pub extern crate __acl_maxflow as maxflow;
+pub extern crate __acl_mincostflow as mincostflow;
+pub extern crate __acl_modint as modint;
+pub extern crate __acl_scc as scc;
+pub extern crate __acl_segtree as segtree;
+pub extern crate __acl_string as string;
+pub extern crate __acl_twosat as twosat;
 
-pub(crate) mod internal_bit;
-pub(crate) mod internal_math;
-pub(crate) mod internal_queue;
-pub(crate) mod internal_scc;
-pub(crate) mod internal_type_traits;
+// Crates like `num` re-export sub crates like this, but currently `cargo-simple-bundler` does not support inline modules.
+//pub mod twosat {
+//    extern crate __acl_twosat as twosat;
+//    pub use self::twosat::*;
+//}
 
 pub use convolution::{convolution, convolution_i64};
 pub use dsu::Dsu;