diff --git a/caderno.pdf b/caderno.pdf
index 4b60aff95fa63be0f9c9d35e203505322483f7a7..c9fc0a587da84d4d9a66a59ac7c5ddaf87fdd58c 100644
Binary files a/caderno.pdf and b/caderno.pdf differ
diff --git a/caderno/caderno.tex b/caderno/caderno.tex
index 1444998d3504c3d90635f11e8c6c9f4148ab0aca..114f2b982a09bfab2da6b8b30ad7819fe0a46a1e 100644
--- a/caderno/caderno.tex
+++ b/caderno/caderno.tex
@@ -208,6 +208,9 @@ para $a$ e $m$ coprimos.
 
 \importsource{fenwick-range-tree.h}
 
+\subsection{Tabela esparsa}
+\importsource{sparse-table.h}
+
 \subsection{União-busca}
 \importsource{disjoint.h}
 
@@ -235,15 +238,15 @@ para $a$ e $m$ coprimos.
 \subsection{Próximo menor elemento}
 \importsource{nle.h}
 
+\subsection{Conjunto de intervalos coloridos}
+\importsource{interval-set.h}
+
 \subsection{Hash map simples}
 \importsource{simple-hash.h}
 
 \subsection{Hash customizado}
 \importsource{custom-hash.h}
 
-\subsection{Conjunto de intervalos coloridos}
-\importsource{interval-set.h}
-
 \subsection{Árvore de segmentos recursiva}
 \begin{tabular}{l|l|l}
   \hline
@@ -273,12 +276,13 @@ para $a$ e $m$ coprimos.
 \subsection{Árvore de segmentos preguiçosa rec.}
 \importsource{lstrec.h}
 
-\subsection{Árvore de segmentos preguiçosa iter.}
-\importsource{lstit.h}
-
 \subsection{Nó de árvore de segmentos}
 \importsource{node.h}
 
+\clearpage
+\subsection{Árvore de segmentos preguiçosa iter.}
+\importsource{lstit.h}
+
 \section{Grafos}
 
 \subsection{Articulações e Pontes}
@@ -287,6 +291,7 @@ para $a$ e $m$ coprimos.
 \subsection{Stoer-Wagner}
 \importsource{stoer-wagner.h}
 
+\clearpage
 \subsection{Emparelhamento estável}
 \begin{tabular}{l}
   \hline
@@ -331,7 +336,7 @@ para $a$ e $m$ coprimos.
 \subsection{Caminhos mínimos -- Floyd-Warshall}
 \importsource{floyd-warshall.h}
 
-\subsection{Ordenação Topológica}
+\subsection{Ordenação topológica}
 \importsource{topo.h}
 
 \subsection{Árvore geradora mínima -- Prim}
@@ -343,6 +348,10 @@ para $a$ e $m$ coprimos.
 \subsection{Ascensão binária}
 \importsource{bl.h}
 
+\subsection{Menor anc. comum -- Offline}
+\importsource{lca-offline.h}
+
+\clearpage
 \subsection{Menor anc. comum -- Ancensão binária}
 \importsource{bllca.h}
 
@@ -361,12 +370,6 @@ para $a$ e $m$ coprimos.
 \end{tabular}
 \importsource{hld.h}
 
-\subsection{Decomposição raiz quadrada de árvore}
-\importsource{stdt.h}
-
-\subsection{Menor anc. comum -- Dec. raiz quad.}
-\importsource{stdtlca.h}
-
 \subsection{Empar. máximo bipartido -- Kuhn}
 \begin{tabular}{l}
   \hline
@@ -378,13 +381,30 @@ para $a$ e $m$ coprimos.
 \subsection{Empar. máximo bipartido -- Hopcroft}
 \importsource{hopcroft.h}
 
-\section{Matemática}
+\subsection{Decomposição raiz quadrada de árvore}
+\importsource{stdt.h}
 
-\subsection{Problema de Josephus}
+\subsection{Menor anc. comum -- Dec. raiz quad.}
+\importsource{stdtlca.h}
+
+\section{Matemática}
 
 \subsection{Operações comuns}
 \importsource{numbers.h}
 
+\subsection{Compressão de coordenadas}
+\importsource{coordmap.h}
+
+\subsection{Sequência de Bruijn}
+Número de sequências distintas:
+\begin{align*}
+  \frac{(k!)^{k^{n-1}}}{k^n}
+\end{align*}
+\importsource{bruijn.h}
+
+\subsection{Problema de Josephus}
+\importsource{josephus.h}
+
 \subsection{Primeiros e últimos digitos de $n^k$}
 \importsource{nk-first-last-digits.h}
 
@@ -512,6 +532,7 @@ ax + by = c
 \subsection{Miller-Rabin}
 \importsource{miller-rabin.h}
 
+\clearpage
 \subsection{Pollard Rho}
 \begin{tabular}{l}
   \hline
@@ -556,6 +577,7 @@ $z[i]$ é o tamanho da maior string que é ao mesmo tempo, um prefixo de $s$ e u
 
 \importsource{z.h}
 
+\clearpage
 \subsection{KMP}
 \begin{tabular}{l|l}
   \hline
@@ -601,9 +623,6 @@ $z[i]$ é o tamanho da maior string que é ao mesmo tempo, um prefixo de $s$ e u
 \end{tabular}
 \importsource{graham.h}
 
-\subsection{Interseção de retângulos}
-\importsource{rectangle-intersection.h}
-
 \subsection{Ponto dentro do polígono?}
 \importsource{isinsidepoly.h}
 
@@ -625,54 +644,76 @@ A = i + b/2 - 1
 \subsection{Ponto e segmento}
 \importsource{pointseg.h}
 
+\subsection{Interseção de retângulos}
+\importsource{rectangle-intersection.h}
+
 \subsection{Segmento e segmento}
 \importsource{segseg.h}
 
 \subsection{Árvore KD}
 \importsource{kd-tree.h}
 
-\subsection{Varredura linear*}
-
 \subsection{Varredura angular}
 \importsource{angular-sweep.h}
 
-\section{Problemas}
-\subsection{Rainhas no tabuleiro*}
+\section{Algoritmos}
 
-\subsection{Soma em subvetor*}
+\subsection{Agendamento ótimo de tarefas}
+\importsource{jobs.h}
 
-\subsection{Remoção de valores com deque*}
+\subsection{Ordenação por fusão}
+\importsource{mergesort.h}
 
-\subsection{Remoção de valores com lista*}
+\subsection{Subconjuntos de tamanho $K$}
+\importsource{combination.h}
 
-\subsection{Embarcadouro*}
+\subsection{Algoritmo de Mo}
+\importsource{mo.h}
 
-\section{Algoritmos}
-\subsection{Ordenação por fusão*}
-\importsource{merge-sort.h}
+\subsection{Meet in the middle}
+\importsource{meet.h}
 
-\subsection{Mochila com recuperação*}
+\subsection{Maior subvetor com soma $s$}
+\importsource{subsum.h}
 
-\subsection{Permutações*}
+\subsection{Maior subsequência crescente}
+\importsource{lis.h}
 
-\subsection{Algoritmo de Mo*}
+\subsection{Maior subsequência crescente rápido}
+\importsource{lisnlgn.h}
 
-\subsection{Meet in the middle*}
+\subsection{PD de perfil quebrado}
+\importsource{parquet.h}
 
-\subsection{Maior subsequência crescente*}
-\importsource{lis.cpp}
+\subsection{Busca binária}
+\importsource{bs.h}
 
-\subsection{Maior subsequência crescente mais rápido*}
-\importsource{lisnlgn.cpp}
+\subsection{Máscaras de bit e operações em bit}
+\importsource{bitmask.h}
 
-\subsection{PD de perfil quebrado*}
+\subsection{Busca binária diferentona}
+\importsource{binarystep.h}
 
-\subsection{Busca binária}
-\importsource{bs.h}
+\section{Problemas}
+\subsection{Rainhas no tabuleiro}
+\importsource{queens.h}
+
+\subsection{Moda usando algoritmo de Mo}
+\importsource{mode.h}
+
+\subsection{Inversões usando algoritmo de Mo}
+\importsource{inversionmo.h}
+
+\subsection{Remoção de valores com lista}
+\importsource{remove.h}
+
+\subsection{Remoção de valores com deque}
+\importsource{removedeque.h}
 
-\subsection{Busca binária diferentona*}
+\subsection{Desembarcadouro}
+\importsource{desembarcadouro.h}
 
-\subsection{Máscaras de bit e operações em bit*}
-\importsource{bit-ops.cpp}
+\subsection{Distância de Edição}
+\importsource{edit-distance.h}
 
 \end{document}
diff --git a/fontes/binarystep.h b/fontes/binarystep.h
new file mode 100644
index 0000000000000000000000000000000000000000..0aa69e916baba9e58683c125e70d2824d9b9001a
--- /dev/null
+++ b/fontes/binarystep.h
@@ -0,0 +1,9 @@
+int count(vector<int>& v, int x) {
+  int n = v.size();
+  int l = n, r = n;
+  for (int p = n; p >= 1; p /= 2) {
+    while (l-p >= 0 && !(v[l-p] < 2)) { l -= p; }
+    while (r-p >= 0 && !(v[r-p] <= 2)) { r -= p; }
+  }
+  return r - l;
+}
diff --git a/fontes/bit-ops.cpp b/fontes/bitmask.h
similarity index 50%
rename from fontes/bit-ops.cpp
rename to fontes/bitmask.h
index 6b589436052964decf4cd273693b0dda7202dbc0..fc49afd8c0db70f9119f0927df94f36b4d6b9f42 100644
--- a/fontes/bit-ops.cpp
+++ b/fontes/bitmask.h
@@ -1,3 +1,3 @@
 for (int s = 0; s < (1LL<<n); s++)
 for (int ss = s; ss > 0; ss = (ss-1)&s)
-  minCost[i][s] = min(minCost[i][s], minCost[i][ss] + minCost[i][s-ss]);
+  c[i][s] = min(c[i][s], c[i][ss] + c[i][s-ss]);
diff --git a/fontes/bruijn.h b/fontes/bruijn.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d09f534bfe9ac43c1f5c07080d412cbaeaae938
--- /dev/null
+++ b/fontes/bruijn.h
@@ -0,0 +1,14 @@
+vector<int> a (K*N, 0);
+vector<int> seq;
+
+void de_bruijn(int k, int n, int t=1, int p=1) {
+  if (t > n && n % p == 0)
+    seq.insert(end(seq), begin(a)+1, begin(a)+p+1);
+  if (t > n) { return; }
+  a[t] = a[t - p];
+  de_bruijn(k, n, t+1, p);
+  for (int j = a[t-p]+1; j < k; j++) {
+    a[t] = j;
+    de_bruijn(k, n, t+1, t);
+  }
+}
diff --git a/fontes/bs.h b/fontes/bs.h
index d761a7d724b9b576a769ef5208cca47b096707cd..46ebc2907e44286c2415e70761870dfac2165803 100644
--- a/fontes/bs.h
+++ b/fontes/bs.h
@@ -1,16 +1,9 @@
 ll binary_search(ll lo, ll hi) {
   while (lo < hi) {
     ll mid = lo + (hi-lo) / 2;
-    if (P(mid)) {
-      hi = mid;
-    } else {
-      lo = mid + 1;
-    }
+    if (P(mid)) { hi = mid; }
+    else { lo = mid + 1; }
   }
-
-  if (!P(lo)) {
-    // P(x) is false for all x in S
-  }
-
+  if (!P(lo)) { /* P(x) is false for all x in S */ }
   return lo;
 }
diff --git a/fontes/combination.h b/fontes/combination.h
new file mode 100644
index 0000000000000000000000000000000000000000..ef6b7cae1a4f7fa87fafc1171095ef5bd41c269f
--- /dev/null
+++ b/fontes/combination.h
@@ -0,0 +1,12 @@
+bool next_combination(vector<int>& a, int n) {
+  int k = a.size();
+  for (int i = k - 1; i >= 0; i--) {
+    if (a[i] < n - k + i + 1) {
+      a[i]++;
+      for (int j = i + 1; j < k; j++)
+        a[j] = a[j - 1] + 1;
+      return true;
+    }
+  }
+  return false;
+}
diff --git a/fontes/coordmap.h b/fontes/coordmap.h
new file mode 100644
index 0000000000000000000000000000000000000000..26299316f82b591e87c91d11dc5022b6ccf90c29
--- /dev/null
+++ b/fontes/coordmap.h
@@ -0,0 +1,8 @@
+void compress(vector<int>& v, vector<int>& cv) {
+  set<int> vs (v.begin(), v.end());
+  map<int, int> to, fm;
+  int ix = 0;
+  for (int i : vs) { to[i] = ix; fm[ix] = i; ix++; }
+  for (int i = 0; i < v.size(); i++)
+    cv[i] = to[v[i]];
+}
diff --git a/fontes/desembarcadouro.h b/fontes/desembarcadouro.h
new file mode 100644
index 0000000000000000000000000000000000000000..09e73c6932d50ebf9cbf45d21c758616007fa5f4
--- /dev/null
+++ b/fontes/desembarcadouro.h
@@ -0,0 +1,20 @@
+const int K = 300;
+vector<int> containers (100001);
+vector<vector<int>> dp (100001 + K, vector<int>(K));
+int main() {
+  int n, q; cin >> n >> q;
+  while (q--) {
+    int a, l, d; cin >> a >> l >> d;
+    if (d >= K)
+      for (int i = 0; i < l; i++) { containers[a + i * d]++; }
+    else { dp[a][d]++; dp[a + (l * d)][d]--; }
+  }
+  for (int j = 1; j < K; j++)
+    for (int i = j; i < n + 1; i++)
+      dp[i][j] += dp[i - j][j];
+  for (int i = 1; i <= n; i++) {
+    for (int j = 1; j < K; j++)
+      containers[i] += dp[i][j];
+    cout << containers[i] << ' ';
+  }
+}
diff --git a/fontes/edit-distance.h b/fontes/edit-distance.h
new file mode 100644
index 0000000000000000000000000000000000000000..7fb89626e78310f26dec2b52d2370f79078aac3c
--- /dev/null
+++ b/fontes/edit-distance.h
@@ -0,0 +1,29 @@
+void edit_distance(string s1, s2) {
+  int n1 = s1.size(), n2 = s2.size();
+  vector<vector<int>> dist (n1+1, vector<int>(n2+1));
+  vector<vector<int>> op (n1+1, vector<int>(n2+1));
+  for (int i = 1; i <= n1; i++) {
+    dist[i][0] = i; op[i][0] = 3;
+  }
+  for (int j = 1; j <= n2; j++) {
+    dist[0][j] = j; op[0][j] = 2;
+  }
+  for (int i = 1; i <= n1; i++)
+    for (int j = 1; j <= n2; j++) {
+      int bdist, bop;
+      if (s1[i-1] == s2[j-1]) {
+        // Skip
+        bdist = dist[i-1][j-1]; bop = 0;
+      } else {
+        int repl = dist[i-1][j-1] + 1;
+        bdist = repl; bop = 1;
+        int ins = dist[i][j-1] + 1;
+        if (ins < bdist) { bdist = ins; bop = 2; }
+        int del = dist[i-1][j] + 1;
+        if (del < bdist) { bdist = del; bop = 3; }
+      }
+      dist[i][j] = bdist;
+      op[i][j] = bop;
+    }
+  return dist[n1][n2];
+}
diff --git a/fontes/floyd-warshall.h b/fontes/floyd-warshall.h
index 510f550260ebf915fc71051dd5fb0b8905f104dc..df7d13beb6196e1fae48f43135d3528c61d67213 100644
--- a/fontes/floyd-warshall.h
+++ b/fontes/floyd-warshall.h
@@ -1,6 +1,6 @@
 vector<vector<ll>> d (N, vector<ll>(N, oo));
 
-int floydwarshall(int n) {
+void floydwarshall(int n) {
   for (int u = 0; u < n; u++)
     d[u][u] = 0;
   for (int m = 0; m < n; m++)
diff --git a/fontes/floyd.h b/fontes/floyd.h
index 586099bfc2e6275a05da81ebd06af14ab2abeff8..06eabe47309148af0fc57e1346589c73529a759e 100644
--- a/fontes/floyd.h
+++ b/fontes/floyd.h
@@ -1,14 +1,11 @@
 struct cyc { ll prev, first, len; };
 cyc find_cycle(ll start) {
-    ll a = start, b = start;
-    do {
-        a = succ(a);
-        b = succ(succ(b));
-    } while (a != b);
-    a = start;
-    ll prev = -1;
-    while (a != b) { prev = a; a = succ(a); b = succ(b); }
-    ll len = 0;
-    do { b = succ(b); len++; } while (a != b);
-    return { .prev = prev, .first = a, .len = len };
+  ll a = start, b = start;
+  do { a = succ(a); b = succ(succ(b)); } while (a != b);
+  a = start;
+  ll prev = -1;
+  while (a != b) { prev = a; a = succ(a); b = succ(b); }
+  ll len = 0;
+  do { b = succ(b); len++; } while (a != b);
+  return { .prev = prev, .first = a, .len = len };
 }
diff --git a/fontes/floydhash.h b/fontes/floydhash.h
deleted file mode 100644
index b0a3fade7b4eaf7ba16007efaddfa826dc0cc988..0000000000000000000000000000000000000000
--- a/fontes/floydhash.h
+++ /dev/null
@@ -1,16 +0,0 @@
-ll polyhash(string const& s) {
-    ll h = 0, p = 1;
-    for (char c : s) {
-        h += (c-'a'+1) * p; h %= M;
-        p *= P; p %= M; }
-    return h;
-}
-string gen(ll u) {
-    mt19937_64 rnd (u); u = rnd();
-    string s;
-    while (u) { s += ('a'+(u%26)); u /= 26; }
-    return s;
-}
-ll succ(ll u) {
-    return polyhash(gen(u));
-}
diff --git a/fontes/gen.cpp b/fontes/gen.cpp
index 9d9c432246b52a77f1630b1c1a079479f3c27a3a..f23704652c06671e7d25539b2a3dfeeee2f147e7 100644
--- a/fontes/gen.cpp
+++ b/fontes/gen.cpp
@@ -1,19 +1,11 @@
-#include <bits/stdc++.h>
-using namespace std; using ll = long long;
-
 mt19937 rnd;
-
 ll gen(ll a, ll b) {
   uniform_int_distribution<ll> dist (a, b);
   return dist(rnd);
 }
-
 int main(int argc, char* argv[]) {
-  cin.tie(0); ios_base::sync_with_stdio(0);
   if (argc < 2) {
-    cerr << "usage: " << argv[0] << " <seed>\n";
-    return 1;
+    cerr << "usage: " << argv[0] << " <seed>\n"; return 1;
   }
   rnd = mt19937(atoi(argv[1]));
-  cout << gen(1, 10) << "\n";
 }
diff --git a/fontes/interval-set.h b/fontes/interval-set.h
index 6368c3aac30bff72acd07da01a1a50b0988c2708..5946f8642497ce888505ab7255600ad6179fc1ea 100644
--- a/fontes/interval-set.h
+++ b/fontes/interval-set.h
@@ -3,11 +3,8 @@ struct itvl {
   itvl(int _a, int _b, int _c)
     : a(_a), b(_b), c(_c) {}
   bool operator<(const itvl& o) const {
-    return ii(b, a) < ii(o.b, o.a);
-  }
-  bool operator<(const int& o) const {
-    return b < o;
-  }
+    return ii(b, a) < ii(o.b, o.a); }
+  bool operator<(const int& o) const { return b < o; }
 };
 
 set<itvl, less<>>& si;
@@ -29,8 +26,7 @@ void ins_in(itvl in) {
 void upd_color(int a, int b, int c) {
   auto it = si.lower_bound(b);
   if (it != si.end()) {
-    itvl ori = *it;
-    si.erase(it);
+    itvl ori = *it; si.erase(it);
     if (ori.a < a) { ins_in(itvl(ori.a, a-1, v)); }
     if (ori.b > b) { ins_in(itvl(b+1, ori.b, v)); }
   }
diff --git a/fontes/inversionmo.h b/fontes/inversionmo.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69a729de8fd28db83ff8c4d8708c65f4b408965
--- /dev/null
+++ b/fontes/inversionmo.h
@@ -0,0 +1,12 @@
+ll ans = 0;
+void ins(int i, char dir) {
+  if (dir == 'l') { ans += query(v[i]-1); }
+  else { ans += query(N) - query(v[i]); }
+  add(v[i], +1);
+}
+void rem(int i, char dir) {
+  if (dir == 'l') { ans -= query(v[i]-1); }
+  else { ans -= query(N) - query(v[i]); }
+  add(v[i], -1);
+}
+ll get_ans() { return ans; }
diff --git a/fontes/jobs.h b/fontes/jobs.h
new file mode 100644
index 0000000000000000000000000000000000000000..140d965d32d7de4f93e6d2cc7d8ae9c894624736
--- /dev/null
+++ b/fontes/jobs.h
@@ -0,0 +1,25 @@
+struct job {
+  int deadline, duration, idx;
+  bool operator<(job o) const { return deadline < o.deadline; }
+};
+
+vector<int> compute_schedule(vector<job> jobs) {
+  sort(jobs.begin(), jobs.end());
+  set<pair<int,int>> s; vector<int> schedule;
+  for (int i = jobs.size()-1; i >= 0; i--) {
+    int t = jobs[i].deadline - (i ? jobs[i-1].deadline : 0);
+    s.insert(make_pair(jobs[i].duration, jobs[i].idx));
+    while (t && !s.empty()) {
+      auto it = s.begin();
+      if (it->first <= t) {
+        t -= it->first;
+        schedule.push_back(it->second);
+      } else {
+        s.insert(make_pair(it->first - t, it->second));
+        t = 0;
+      }
+      s.erase(it);
+    }
+  }
+  return schedule;
+}
diff --git a/fontes/josephus.h b/fontes/josephus.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9ea0cf86735420d80e9d90815c5abef225980c1
--- /dev/null
+++ b/fontes/josephus.h
@@ -0,0 +1,15 @@
+int rec(int n, int k) {
+  return (rec(n-1, k) + k) % n;
+}
+
+int klogn(int n, int k) {
+  if (n == 1) { return 0; }
+  if (k == 1) { return n-1; }
+  if (k > n) { return (klogn(n-1, k) + k) % n; }
+  int cnt = n / k;
+  int res = klogn(n - cnt, k);
+  res -= n % k;
+  if (res < 0) { res += n; }
+  else { res += res / (k - 1); }
+  return res;
+}
diff --git a/fontes/karatsuba.h b/fontes/karatsuba.h
index d3ca7812bf8ed49036f288b68073c93891158a43..cb0e33b64b9f8cc326782d34e9514e7b57eec2f7 100644
--- a/fontes/karatsuba.h
+++ b/fontes/karatsuba.h
@@ -2,41 +2,26 @@ vector<ll> karatsuba(const vector<ll> &a,
     const vector<ll> &b) {
   int n = a.size();
   vector<ll> res(n + n);
-
   if (n <= 32) {
     for (int i = 0; i < n; i++)
       for (int j = 0; j < n; j++)
         res[i + j] += a[i] * b[j];
-
     return res;
   }
-
   int k = n >> 1;
   vector<ll> a1(a.begin(), a.begin() + k);
   vector<ll> a2(a.begin() + k, a.end());
   vector<ll> b1(b.begin(), b.begin() + k);
   vector<ll> b2(b.begin() + k, b.end());
-
   vector<ll> a1b1 = karatsuba(a1, b1);
   vector<ll> a2b2 = karatsuba(a2, b2);
-
-  for (int i = 0; i < k; i++)
-    a2[i] += a1[i];
-  for (int i = 0; i < k; i++)
-    b2[i] += b1[i];
-
+  for (int i = 0; i < k; i++) a2[i] += a1[i];
+  for (int i = 0; i < k; i++) b2[i] += b1[i];
   vector<ll> r = karatsuba(a2, b2);
-  for (int i = 0; i < a1b1.size(); i++)
-    r[i] -= a1b1[i];
-  for (int i = 0; i < a2b2.size(); i++)
-    r[i] -= a2b2[i];
-
-  for (int i = 0; i < r.size(); i++)
-    res[i + k] += r[i];
-  for (int i = 0; i < a1b1.size(); i++)
-    res[i] += a1b1[i];
-  for (int i = 0; i < a2b2.size(); i++)
-    res[i + n] += a2b2[i];
-
+  for (int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i];
+  for (int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i];
+  for (int i = 0; i < r.size(); i++) res[i+k] += r[i];
+  for (int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i];
+  for (int i = 0; i < a2b2.size(); i++) res[i+n] += a2b2[i];
   return res;
 }
diff --git a/fontes/kd-tree.h b/fontes/kd-tree.h
index 2e62a459117c5e9b1c17f063bdeccb106d8dd7cf..60cea2552a7322393bc0b8a818823d743d3200da 100644
--- a/fontes/kd-tree.h
+++ b/fontes/kd-tree.h
@@ -1,6 +1,6 @@
 int get_ii(pt pair, int ix) {
-    if (ix == 0) { return pair.px; }
-    else { return pair.py; }
+  if (ix == 0) { return pair.px; }
+  else { return pair.py; }
 }
 
 class kdtree {
diff --git a/fontes/kuhn.h b/fontes/kuhn.h
index 07e43a93cf9c28694d10adef89d4a2ba43b2423e..f5fee6fb6d8355659b9401ef0192e9e95011aaab 100644
--- a/fontes/kuhn.h
+++ b/fontes/kuhn.h
@@ -1,4 +1,3 @@
-// u e v são enumerações distintas (podem repetir)
 vector<vector<int>> g (L);
 vector<int> matchr (R, -1);
 
diff --git a/fontes/latticepoints.h b/fontes/latticepoints.h
index 07fcbf13d44a91555c65776390dcc5309971f058..14bc9a0b057f58b1fc44aa8f672558db7f2fddf1 100644
--- a/fontes/latticepoints.h
+++ b/fontes/latticepoints.h
@@ -2,14 +2,12 @@ ll lattice_points(vector<pt>& ps) {
   ll b = 0;
   for (int i = 0; i < n; i++) {
     pt v = vec(ps[i], ps[(i+1)%n]);
-    if (v.py == 0) {
+    if (v.py == 0)
       b += abs(v.px);
-    } else if (v.px == 0) {
+    else if (v.px == 0)
       b += abs(v.py);
-    } else {
+    else
       b += gcd(abs(v.px), abs(v.py));
-    }
   }
-
   return poly_area(ps) - b/2 + 1;
 }
diff --git a/fontes/lca-offline.h b/fontes/lca-offline.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee011d3dbe0dd2c6858b776e4c1a7d67bbbffede
--- /dev/null
+++ b/fontes/lca-offline.h
@@ -0,0 +1,14 @@
+vector<vector<int>> queries (N);
+vector<int> anc (N); vector<bool> vis (N);
+
+void dfs(int u) {
+  vis[u] = true;
+  anc[u] = u;
+  for (int v : adj[u]) if (!vis[v]) {
+    dfs(v);
+    ds_unite(u, v);
+    anc[ds_find(u)] = u;
+  }
+  for (int v : queries[u]) if (vis[v])
+    lca[u][v] = anc[ds_find(v)];
+}
diff --git a/fontes/lcm.cpp b/fontes/lcm.cpp
deleted file mode 100644
index ddbbb5dcf97926ce626995ea1cb981cbfe7c02e2..0000000000000000000000000000000000000000
--- a/fontes/lcm.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-int lcm(int a, int b) {
-  return a*b / __gcd(a, b);
-}
diff --git a/fontes/lis.cpp b/fontes/lis.cpp
deleted file mode 100644
index fe37a36e47e287f5a28c17d64104eadb142f12b4..0000000000000000000000000000000000000000
--- a/fontes/lis.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-int n; while (cin >> n) {
-  fill(dp.begin(), dp.end(), 1); // base
-  for (int i = 0; i < n; i++) {
-    cin >> v[i];
-    for (int j = 0; j < i; j++) if (v[j] < v[i])
-      dp[i] = max(dp[i], 1 + dp[j]);
-  }
-  cout << *max_element(dp.begin(), dp.end()) << "\n";
-}
diff --git a/fontes/lis.h b/fontes/lis.h
new file mode 100644
index 0000000000000000000000000000000000000000..105686802da562f27bc1ed769b63aeb41e79a26f
--- /dev/null
+++ b/fontes/lis.h
@@ -0,0 +1,8 @@
+vector<int> dp (N, 1);
+
+int lis(vector<int>& v) {
+  for (int i = 0; i < v.size(); i++)
+    for (int j = 0; j < i; j++) if (v[j] < v[i])
+      dp[i] = max(dp[i], 1 + dp[j]);
+  return *max_element(dp.begin(), dp.end());
+}
diff --git a/fontes/lisnlgn.cpp b/fontes/lisnlgn.h
similarity index 61%
rename from fontes/lisnlgn.cpp
rename to fontes/lisnlgn.h
index f3dda8b052f697802c123260ef6b16757d7d60d1..8c4f4d684b10f79021f0d63f9690563da96b3391 100644
--- a/fontes/lisnlgn.cpp
+++ b/fontes/lisnlgn.h
@@ -1,8 +1,9 @@
-int n; while (cin >> n) {
-  fill(dp.begin(), dp.begin()+n+1, oo);
+vector<int> dp (N, oo);
+
+int lis(vector<int>& v) {
+  int n = v.size();
   dp[0] = -oo;
   for (int i = 0; i < n; i++) {
-    cin >> v[i];
     int j = upper_bound(dp.begin(),
         dp.begin()+n+1, v[i]) - dp.begin();
     if (dp[j-1] < v[i] && v[i] < dp[j])
@@ -10,6 +11,5 @@ int n; while (cin >> n) {
   }
   for (int i = 0; i <= n; i++) if (dp[i] == oo)
       dp[i] = -oo;
-  cout << max_element(dp.begin(),
-      dp.begin()+n+1) - dp.begin() << "\n";
+  return max_element(dp.begin(), dp.begin()+n+1) - dp.begin();
 }
diff --git a/fontes/meet.h b/fontes/meet.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c403e41253e54629fa1fa5d2237b4c04fbc0949
--- /dev/null
+++ b/fontes/meet.h
@@ -0,0 +1,17 @@
+int mitm(vector<int>& v, int x) {
+  int n = v.size();
+  map<ll, int> sums; ll c = 0;
+  for (int ss = 0; ss < 1<<(n/2); ss++) {
+    ll s = 0;
+    for (int i = 0; i < n/2; i++) if (1<<i & ss)
+      s += v[i];
+    if (s <= x) { sums[s]++; }
+  }
+  for (int ss = 0; ss < 1<<(n/2+n%2); ss++) {
+    ll s = 0;
+    for (int i = n/2; i < n; i++) if (1<<(i-n/2) & ss)
+      s += v[i];
+    if (sums.count(x - s)) { c += sums[x - s]; }
+  }
+  return c;
+}
diff --git a/fontes/merge-sort.h b/fontes/merge-sort.h
deleted file mode 100644
index 0fbd62d27442fca8ab109b55f62d24d00974b62b..0000000000000000000000000000000000000000
--- a/fontes/merge-sort.h
+++ /dev/null
@@ -1,29 +0,0 @@
-vector<int> v (1e4);
-
-int merge_sort(int a, int b) {
-  // already sorted
-  if (a+1 == b) { return 0; }
-
-  int swaps = 0;
-
-  int m = a+(b-a)/2;
-  swaps += merge_sort(a, m);
-  swaps += merge_sort(m, b);
-
-  vector<int> aux (b - a);
-  int f = a, s = m;
-  for (int i = 0; i < b - a; i++) {
-    if (s < b && f < m && v[f] > v[s]) {
-      // inversion
-      swaps += m-f;
-    }
-    if ((!(s < b) || v[f] < v[s]) && f < m) {
-      aux[i] = v[f++];
-    } else {
-      aux[i] = v[s++];
-    }
-  }
-
-  copy(aux.begin(), aux.end(), v.begin()+a);
-  return swaps;
-}
diff --git a/fontes/mergesort.h b/fontes/mergesort.h
new file mode 100644
index 0000000000000000000000000000000000000000..b13da7ac8043b6591fc42db8ceb317ac58204343
--- /dev/null
+++ b/fontes/mergesort.h
@@ -0,0 +1,17 @@
+int swaps = 0;
+void merge_sort(int l, int r) {
+  if (r - l == 1) { return; }
+  int mi = l + (r - l) / 2;
+  merge_sort(l, mi); merge_sort(mi, r);
+  vector<int> aux (r - l);
+  int i = l, j = mi;
+  for (int k = 0; k < r - l; k++) {
+    if (i < mi && j < r) {
+      if (!(a[i] < a[j])) { swaps += mi - i; }
+      if (a[i] < a[j]) { aux[k] = a[i++]; }
+      else { aux[k] = a[j++]; }
+    } else if (i < mi) { aux[k] = a[i++]; }
+    else { aux[k] = a[j++]; }
+  }
+  copy(aux.begin(), aux.end(), a.begin()+l);
+}
diff --git a/fontes/miller-rabin.h b/fontes/miller-rabin.h
index 783e61e7d901c3f23094d27441065234f76afd54..e14a42079721c6f60053bda7d1a5207ea61b0bd8 100644
--- a/fontes/miller-rabin.h
+++ b/fontes/miller-rabin.h
@@ -1,5 +1,4 @@
-using ll = long long; using i128 = __int128_t;
-
+using i128 = __int128_t;
 ll binary_pow(ll a, ll e, ll m) {
   if (e == 0) { return 1; }
   if (e == 1) { return a; }
@@ -10,10 +9,7 @@ ll binary_pow(ll a, ll e, ll m) {
 }
 
 vector<int> witnesses = {
-  // primes from 2 to 37, enough for 64 bits
-  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37
-};
-
+  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 };
 bool is_prime(ll n) {
   if (n < 2) { return false; }
   int s = __lg((n-1)&-(n-1));
diff --git a/fontes/mo.h b/fontes/mo.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6dad023cb749f5dc5c9e4dd3affe2f0fb480394
--- /dev/null
+++ b/fontes/mo.h
@@ -0,0 +1,17 @@
+vector<int> mo(vector<qry> qs) {
+  vector<int> ans (qs.size());
+  sort(qs.begin(), qs.end(), [](qry a, qry b) {
+    if (a.l/B != b.l/B)
+      return make_pair(a.l, a.r) < make_pair(b.l, b.r);
+    return (a.l/B) % 2 ? a.r < b.r : a.r > b.r;
+  });
+  int l = 0, r = -1;
+  for (qry q : qs) {
+    while (l > q.l) { l--; ins(l, 'l'); }
+    while (r < q.r) { r++; ins(r, 'r'); }
+    while (l < q.l) { rem(l, 'l'); l++; }
+    while (r > q.r) { rem(r, 'r'); r--; }
+    ans[q.ix] = get_ans();
+  }
+  return ans;
+}
diff --git a/fontes/mode.h b/fontes/mode.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed9fa540cc2f03f5a16d7024aa93f839520859ee
--- /dev/null
+++ b/fontes/mode.h
@@ -0,0 +1,15 @@
+vector<int> v (N), freqfreq (N), freq (N);
+int ans = 0;
+void ins(int i, char dir) {
+    freqfreq[freq[v[i]]]--;
+    freq[v[i]]++;
+    freqfreq[freq[v[i]]]++;
+    if (freqfreq[ans+1]) { ans++; }
+}
+void rem(int i, char dir) {
+    freqfreq[freq[v[i]]]--;
+    freq[v[i]]--;
+    freqfreq[freq[v[i]]]++;
+    if (ans > 0 && freqfreq[ans] == 0) { ans--; }
+}
+int get_ans() { return ans; }
diff --git a/fontes/neighbors.cpp b/fontes/neighbors.cpp
deleted file mode 100644
index 44eb476c932bd8ca8d37a08b50ed7ea3504773ba..0000000000000000000000000000000000000000
--- a/fontes/neighbors.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// 4 neighbors
-vector<int> dxy = { +1, 0, -1, 0, +1 };
-for (int k = 0; k < 4; k++) {
-  int di = dxy[k], dj = dxy[k+1];
-  cout << di << " " << dj << "\n";
-}
-
-// 8 neighbors
-for (int di : { -1, 0, +1 }) {
-for (int dj : { -1, 0, +1 }) {
-  if (di == 0 && dj == 0) { continue; }
-  cout << di << " " << dj << "\n";
-}
-}
diff --git a/fontes/parquet.h b/fontes/parquet.h
new file mode 100644
index 0000000000000000000000000000000000000000..d349155f0d759647516873b93b405f9ebdad42c4
--- /dev/null
+++ b/fontes/parquet.h
@@ -0,0 +1,21 @@
+vector<vector<ll>> dp (N+1, vector<ll>(1LL<<M));
+
+void calc(int x = 0, int y = 0, int s = 0, int nxts = 0) {
+  if (x == n) { return; }
+  if (y >= m) { dp[x+1][nxts] += dp[x][s]; return; }
+  int cs = 1 << y;
+  if (s & cs) { calc(x, y+1, s, nxts); }
+  else {
+    calc(x, y+1, s, nxts | cs);
+    if (y+1 < m && ! (s & cs) && ! (s & (cs << 1)))
+      calc(x, y+2, s, nxts);
+  }
+}
+
+int solve() {
+  dp[0][0] = 1;
+  for (int x = 0; x < n; x++)
+    for (int s = 0; s < (1<<m); s++)
+      calc(x, 0, s, 0);
+  return dp[n][0];
+}
diff --git a/fontes/queens.h b/fontes/queens.h
new file mode 100644
index 0000000000000000000000000000000000000000..bda2ad23744846b8c335a69327bfb7df7582ed7d
--- /dev/null
+++ b/fontes/queens.h
@@ -0,0 +1,9 @@
+int n, s;
+void queens(int i, ll rw = 0, ll ld = 0, ll rd = 0) {
+  if (rw == (1<<n)-1) { s++; return; }
+  ll pos = ((1<<n)-1) & (~(rw | ld | rd));
+  while (pos) {
+    ll p = pos & -pos; pos -= p;
+    queens(i+1, rw | p, (ld | p) << 1, (rd | p) >> 1);
+  }
+}
diff --git a/fontes/remove.h b/fontes/remove.h
new file mode 100644
index 0000000000000000000000000000000000000000..84d9ef568152358349d0f2fd3bfb84da25b066f9
--- /dev/null
+++ b/fontes/remove.h
@@ -0,0 +1,20 @@
+list<int> l; vector<int> bsz (N/B + 1);
+vector<list<int>::iterator> bbegin (N/B + 1);
+vector<int> remove(vector<int>& v, vector<int>& r) {
+  vector<int> ans;
+  int n = v.size();
+  for (int i = 0; i < n; i++) {
+    auto ins = l.insert(l.end(), v[i]);
+    if (i % B == 0) { bbegin[i/B] = ins; }
+    bsz[i/B]++;
+  }
+  for (int i : r) {
+    auto it = bbegin[i/B]; advance(it, i%B);
+    if (i % B == 0) { bbegin[i/B]++; }
+    ans.push_back(*it); l.erase(it);
+    int bi = i/B;
+    while (bsz[bi+1] > 0) { bbegin[bi+1]++; bi++; }
+    bsz[bi]--;
+  }
+  return ans;
+}
diff --git a/fontes/removedeque.h b/fontes/removedeque.h
new file mode 100644
index 0000000000000000000000000000000000000000..68394aaf90235a83467044a4d8810065cc3bed7a
--- /dev/null
+++ b/fontes/removedeque.h
@@ -0,0 +1,18 @@
+vector<deque<int>> l (N/B + 1);
+vector<int> remove(vector<int>& v, vector<int>& r) {
+  vector<int> ans;
+  int n = v.size();
+  for (int i = 0; i < n; i++)
+    l[i/B].push_back(v[i]);
+  for (int i : r) {
+    auto it = l[i/B].begin()+(i%B);
+    ans.push_back(*it); l[i/B].erase(it);
+    int bi = i/B;
+    while (l[bi+1].size() > 0) {
+      l[bi+1].push_back(l[bi].back());
+      l[bi].pop_back();
+      bi++;
+    }
+  }
+  return ans;
+}
diff --git a/fontes/sparse-table.h b/fontes/sparse-table.h
new file mode 100644
index 0000000000000000000000000000000000000000..468ca54814e2f3118ac673d97603d939325be434
--- /dev/null
+++ b/fontes/sparse-table.h
@@ -0,0 +1,21 @@
+const int K = 25;
+vector<int> lg (N+1);
+vector<vector<int>> st (N, vector<int>(K+1));
+
+void build(vector<int>& src) {
+  lg[1] = 0;
+  for (int i = 2; i <= N; i++)
+    lg[i] = lg[i/2] + 1;
+
+  for (int i = 0; i < src.size(); i++)
+    st[i][0] = src[i];
+
+  for (int j = 1; j <= K; j++)
+    for (int i = 0; i + (1 << j) <= N; i++)
+      st[i][j] = min(st[i][j-1], st[i + (1 << (j - 1))][j - 1]);
+}
+
+int min_inclusive(int l, int r) {
+  int j = lg[r - l + 1];
+  return min(st[l][j], st[r - (1 << j) + 1][j]);
+}
diff --git a/fontes/stdt.h b/fontes/stdt.h
index fb51d9c81d66c3ea8fac7679f8b9e213765bba81..b5b848b2c7f4ead1b7f4aa7545e53a9f1e1c0652 100644
--- a/fontes/stdt.h
+++ b/fontes/stdt.h
@@ -1,6 +1,5 @@
-vector<int> depth (N);
-vector<int> up (N); vector<int> weiop (N);
-vector<int> bup (N); vector<int> bweiop (N);
+vector<int> up (N), bup (N), depth (N);
+vector<ll> weiop (N), bweiop (N);
 
 void stdt_decompose(int u, int p, int w) {
     up[u] = p; weiop[u] = w;
diff --git a/fontes/subsum.h b/fontes/subsum.h
new file mode 100644
index 0000000000000000000000000000000000000000..675e4b8c27fded7e423cbb3179fd98773b33c6cc
--- /dev/null
+++ b/fontes/subsum.h
@@ -0,0 +1,10 @@
+ii subsum(vector<int>& v, int s) {
+  int n = v.size();
+  int i = 0, j = 1, w = v[0];
+  while (j < n) {
+    while (w + v[j] > s && i < j-1) { w -= v[i++]; }
+    if (w < s) { w += v[j++]; }
+    if (w == s) { return {i, j}; }
+  }
+  return {-1,-1};
+}