diff --git a/fs-succinct/Makefile b/fs-succinct/Makefile
index 60c5d54ce9ba9ecd04e9032b47bdd2600bb19f1b..5db87b33f1bc49531f4c7fbe39c04c7107350e4c 100644
--- a/fs-succinct/Makefile
+++ b/fs-succinct/Makefile
@@ -1,4 +1,9 @@
 TOP=..
-PICS=sole
+PICS=sole sole_boxes sole_hilevel
+
 
 include ../Makerules
+
+sole.pdf:: succinct_common.asy
+sole_boxes.pdf:: succinct_common.asy
+sole_hilevel.pdf:: succinct_common.asy
diff --git a/fs-succinct/sole.asy b/fs-succinct/sole.asy
index 94295808bd8b55700e8187a33552a0bd4e904b5d..8b16f0dcdf070309bbb0d5e947028307546bc0a2 100644
--- a/fs-succinct/sole.asy
+++ b/fs-succinct/sole.asy
@@ -1,4 +1,4 @@
-import sole_common;
+import succinct_common;
 blocks(0 ... concat(array(6,"B"), new string[] {"...", "B", "EOF"}));
 thruarrows(0,0,6);
 thruarrows(0,7,2);
diff --git a/fs-succinct/sole_boxes.asy b/fs-succinct/sole_boxes.asy
new file mode 100644
index 0000000000000000000000000000000000000000..3723f04df0d9fb962006b9ab5d638a33b4516908
--- /dev/null
+++ b/fs-succinct/sole_boxes.asy
@@ -0,0 +1,30 @@
+import succinct_common;
+
+void fillbox(int col, pen pen) {
+    path p = (
+        (col*blockwidth, -rowheight-blockheight)
+        -- ((col+2)*blockwidth, -rowheight-blockheight)
+        -- ((col+2)*blockwidth, -2*rowheight)
+        -- ((col+1)*blockwidth, -2*rowheight)
+        -- ((col+1)*blockwidth, -3*rowheight)
+        -- ((col-1)*blockwidth, -3*rowheight)
+        -- ((col-1)*blockwidth, -2*rowheight-blockheight)
+        -- ((col)*blockwidth, -2*rowheight-blockheight)
+        -- cycle
+        );
+    fill(p, pen);
+    draw(p, thick);
+}
+
+fillbox(2, 0.5*white);
+fillbox(4, 0.75*white);
+fillbox(6, 0.5*white);
+
+//blocks(0 ... concat(array(8,"B"), new string[] {"..."}));
+//thruarrows(0,0,6);
+blocks(1 ... concat(array(8, "B+1"), array(1, "...")) );
+mixarrows(1,0,8);
+blocks(2,  "B", "B+3", "B-3", "B+6", "B-6", "B+9", "B-9", "...");
+thruarrow(2, 0);
+mixarrows(2, 1, 6);
+blocks(3 ... concat(array(7,"B"), array(1, "...")));
diff --git a/fs-succinct/sole_hilevel.asy b/fs-succinct/sole_hilevel.asy
new file mode 100644
index 0000000000000000000000000000000000000000..47bc193e9776e7fcc1dbf95ad26f2a16f60b2ac1
--- /dev/null
+++ b/fs-succinct/sole_hilevel.asy
@@ -0,0 +1,19 @@
+import succinct_common;
+
+real mixgrid = 2.5;
+int nmixers = 3;
+
+for (int i = 0; i < nmixers; ++i) {
+    real x = mixgrid * i;
+    draw((x, 1.25) -- (x, 0.5), e_arrow);
+    label((x, 1.25), "$(B+1)^2$", N);
+    mixer(x, 0);
+    draw((x, -0.5) -- (x, -1.25), e_arrow);
+    label((x, -1.25), "$B^2$", S);
+}
+
+string[] alphas = {"B+3", "B+6", "B+9", "B+12"};
+
+for (int i = 0; i < nmixers+1; ++i) {
+    carry_arrow((mixgrid * (i-1), 0), (mixgrid*i, 0), alphas[i]);
+}
diff --git a/fs-succinct/succinct.tex b/fs-succinct/succinct.tex
index 405b798bfb1437bf64bc8cff86cf74171c12ad33..0f772d95385dbad36f20c89e84000e00047e19ed 100644
--- a/fs-succinct/succinct.tex
+++ b/fs-succinct/succinct.tex
@@ -198,12 +198,39 @@ B^2 + 2B + 1 &\le B^2 + 3B - 9i^2 - 9i\cr
 B            &\ge 9i^2 + 9i + 1\cr
 }$$
 We know $B \ge 4n^2$ and $i \le {n+1\over 2}$. By plugging $i = {n+1\over 2}$
-and doing some algebraic manipulation, we can verify that the inequality holds.
+and $B=4n^2$ and doing some algebraic manipulation, we can verify that the
+inequality holds. For smaller $i$ the right-hand side decreases so it holds
+for those too.
 
 For the second pass, this is trivial, as $(B+i)(B-i) = B^2 - i^2 \le B^2$.
 
-
 \section{Succinct representation of arbitrary-alphabet strings}
 
 
+\subsection{A reinterpretation of the SOLE encoding}
+
+There is another way of looking at the SOLE encoding from the previous section.
+We can group the alphabet translations into ``encoding boxes'' that take input
+from the alphabet $(B+1)^2$, output the alphabet $B^2$ and the part of the
+information that did not fit into the output is passed as a
+``carry''\foot{Sometimes the alternative term {\it spill} is used instead.} to
+the next encoding box (similarly to how carrying works when doing addition).
+See fig. \figref{sole_boxes}.
+
+\figure[sole_boxes]{sole_boxes.pdf}{}{SOLE interpreted as a chain of encoding boxes}
+
+The start and end of the encoding are irregular, but we will ignore that for now.
+An important property of these boxes is that outgoing carry does not depend on incoming
+carry (unlike in addition). This allows for local decoding and modification. Otherwise
+a single input change could affect the whole output. Now we can describe this scheme
+in a more abstract, high-level way (fig. \figref{sole_hilevel}).
+
+\figure[sole_hilevel]{sole_hilevel.pdf}{}{SOLE high-level block diagram}
+
+In our case, the input alphabet size is always $(B+1)^2$, the output alphabet size
+is $B^2$ and the carry alphabet sizes form the sequence $B+3i$. Given that the output
+alphabet is smaller than the input alphabet, it makes sense that the carry alphabet
+has to increase in size to accomodate the accumulating information that did not fit
+into the output. The final carry is then used to output some extra blocks at the end.
+
 \endchapter
diff --git a/fs-succinct/sole_common.asy b/fs-succinct/succinct_common.asy
similarity index 79%
rename from fs-succinct/sole_common.asy
rename to fs-succinct/succinct_common.asy
index 9710212ae8d74591ca48a0ae5544a303322f422e..17d410b9fdeb1e913fb94a677bc014fd779c136b 100644
--- a/fs-succinct/sole_common.asy
+++ b/fs-succinct/succinct_common.asy
@@ -55,4 +55,14 @@ void passlabel(int row, string lbl) {
     label("{\it " + lbl + "}", (-1, -row*rowheight-blockheight - arrowheight/2), W);
 }
 
+void mixer(real x, real y, real r=0.5) {
+    draw((x-r,y-r) -- (x+r,y-r)--(x+r, y+r) -- (x-r, y+r) -- cycle, halfthick);
+    draw( (x,y+r) {S} .. {E} (x+r,y), 0.5*white);
+    draw( (x,y+r) -- (x,y-r), 0.5*white);
+    draw( (x-r,y) {E} .. {S} (x,y-r), 0.5*white);
+}
 
+void carry_arrow(pair mix1, pair mix2, string alphabet) {
+    draw(mix1 + (0.5,0) -- mix2 - (0.5, 0), e_arrow);
+    label((mix1+mix2)/2, "$"+alphabet+"$", N);
+}