diff --git a/src/Warm-Ups/Snakes/0.svg b/src/Warm-Ups/Snakes/0.svg
new file mode 100644
index 0000000..5708d0c
--- /dev/null
+++ b/src/Warm-Ups/Snakes/0.svg
@@ -0,0 +1,81 @@
+
diff --git a/src/Warm-Ups/Snakes/1.svg b/src/Warm-Ups/Snakes/1.svg
new file mode 100644
index 0000000..8dc9ca7
--- /dev/null
+++ b/src/Warm-Ups/Snakes/1.svg
@@ -0,0 +1,161 @@
+
diff --git a/src/Warm-Ups/Snakes/2.svg b/src/Warm-Ups/Snakes/2.svg
new file mode 100644
index 0000000..7f57aa9
--- /dev/null
+++ b/src/Warm-Ups/Snakes/2.svg
@@ -0,0 +1,401 @@
+
diff --git a/src/Warm-Ups/Snakes/3.svg b/src/Warm-Ups/Snakes/3.svg
new file mode 100644
index 0000000..d264b6f
--- /dev/null
+++ b/src/Warm-Ups/Snakes/3.svg
@@ -0,0 +1,1121 @@
+
diff --git a/src/Warm-Ups/Snakes/4.svg b/src/Warm-Ups/Snakes/4.svg
new file mode 100644
index 0000000..8312bb3
--- /dev/null
+++ b/src/Warm-Ups/Snakes/4.svg
@@ -0,0 +1,3281 @@
+
diff --git a/src/Warm-Ups/Snakes/5.svg b/src/Warm-Ups/Snakes/5.svg
new file mode 100644
index 0000000..2dd0e50
--- /dev/null
+++ b/src/Warm-Ups/Snakes/5.svg
@@ -0,0 +1,9761 @@
+
diff --git a/src/Warm-Ups/Snakes/6.svg b/src/Warm-Ups/Snakes/6.svg
new file mode 100644
index 0000000..33b6e99
--- /dev/null
+++ b/src/Warm-Ups/Snakes/6.svg
@@ -0,0 +1,29201 @@
+
diff --git a/src/Warm-Ups/Snakes/7.svg b/src/Warm-Ups/Snakes/7.svg
new file mode 100644
index 0000000..e9d4acc
--- /dev/null
+++ b/src/Warm-Ups/Snakes/7.svg
@@ -0,0 +1,87521 @@
+
diff --git a/src/Warm-Ups/Snakes/main.typ b/src/Warm-Ups/Snakes/main.typ
new file mode 100644
index 0000000..f11f2ce
--- /dev/null
+++ b/src/Warm-Ups/Snakes/main.typ
@@ -0,0 +1,89 @@
+#import "@local/handout:0.1.0": *
+#import "@preview/cetz:0.4.2"
+
+#show: handout.with(
+ title: [Warm-Up: Snakes!],
+ by: "Mark",
+ page_numbers: false,
+)
+
+#box(place(box(width: 100%, height: 8in, align(horizon, image(
+ "7.svg",
+ width: 360mm,
+)))))
+
+#problem()
+Evaluate this integral. \
+All integrals are of the form $integral_a^b 1 #h(1mm) d x$.
+
+#if_solutions(pagebreak())
+
+#solution[
+ This integral is drawn recursively with the following code: \
+
+ #v(2mm)
+
+ #let snake(depth, x, y) = {
+ if depth == 0 {
+ math.attach(math.integral, br: x, tr: y)
+ } else {
+ let bot = snake(depth - 1, x, "1")
+ let top = snake(depth - 1, "0", y)
+ snake(depth - 1, bot, top)
+ }
+ }
+
+ ```typst
+ #let snake(depth, x, y) = {
+ if depth == 0 {
+ $integral_#x ^#y$
+ } else {
+ let bot = snake(depth - 1, x, "1")
+ let top = snake(depth - 1, "0", y)
+ snake(depth - 1, bot, top)
+ }
+ }
+ ```
+
+ #v(5mm)
+
+ For example:
+
+ $ snake\(0, x, y) = #snake(0, "x", "y") $
+
+ #v(2mm)
+
+ $ snake\(1, x, y) = #snake(1, "x", "y") $
+
+ #v(2mm)
+
+ $ snake\(2, x, y) = #snake(2, "x", "y") $
+
+ In other words, we want $f_7 (0, 1)$, where...
+ - $f_0(x, y) := integral_x^y$
+ - $f_(n+1)(x, y) := f_n [f_n (x, 1), f_n (0, y)]$
+
+ #v(5mm)
+ Expanding a few iterations, we find:
+ - $f_0(x, y) = integral_x^y = y-x$
+ - $f_1(x, y) = f_0 [f_0 (x, 1), f_0 (0, y)] = y+x-1$
+ - $f_2(x, y) = f_1 [f_1 (x, 1), f_1 (0, y)] = y+x-2$
+
+ #v(5mm)
+
+ We can use induction to show that this pattern continues. \
+ If $g_n = y+x+c$, then $g_(n+1) = y+x+(3c+1)$.
+
+
+ #v(5mm)
+ Finally, use this recusion to find that
+ $f_0, f_1, ..., f_7 = 1, 0, -1, -4, -13, -40, -121, -364$
+
+ One can also find an explicit formula for $g_n$:
+
+ $
+ f_(n+1) = g_n & = x + y + 3^n c + 3^0 + 3^1 + ... + 3^n \
+ & = x + y + 3^n c + sum_(i=0)^n 3^i \
+ & = x + y + 3^n c + (3^(n+1) + 1)/2
+ $
+]
diff --git a/src/Warm-Ups/Snakes/meta.toml b/src/Warm-Ups/Snakes/meta.toml
new file mode 100644
index 0000000..df3c4a7
--- /dev/null
+++ b/src/Warm-Ups/Snakes/meta.toml
@@ -0,0 +1,6 @@
+[metadata]
+title = "Snakes!"
+
+[publish]
+handout = true
+solutions = true
diff --git a/src/Warm-Ups/Snakes/svg.typ b/src/Warm-Ups/Snakes/svg.typ
new file mode 100644
index 0000000..b840659
--- /dev/null
+++ b/src/Warm-Ups/Snakes/svg.typ
@@ -0,0 +1,57 @@
+#import "@preview/cetz:0.4.2"
+
+// Compile with:
+// typst compile --package-path "../../../lib/typst/" svg.typ --format svg
+// You'll need to recompile typst with a higher recursion limit.
+
+#set page(
+ fill: none,
+ width: auto,
+ height: auto,
+ margin: 0mm,
+);
+
+#let cetz_snake(depth, b, t) = {
+ import cetz.draw: *
+
+ if depth == 0 {
+ content((0, 0), math.inline(math.integral))
+
+ group({
+ translate(x: 0.15, y: -0.15)
+ b
+ })
+
+ group({
+ translate(x: 0.15, y: 0.15)
+ t
+ })
+ } else {
+ let bot = group({
+ translate(x: 0.15, y: -0.15)
+ cetz_snake(depth - 1, b, content((0, 0), text("1", size: 3mm)))
+ })
+
+ let top = group({
+ translate(x: 0.15, y: 0.15)
+ cetz_snake(depth - 1, content((0, 0), text("0", size: 3mm)), t)
+ })
+
+ cetz_snake(depth - 1, bot, top)
+ }
+}
+
+
+#{
+ import cetz.draw: *
+
+ // any bigger than 7 overflows the stack.
+ // any bigger than 5 exceeds typst's recursion limit.
+ // You'll have to increase those limits and recompile to
+ // build this document.
+ let depth = 7
+
+ let b = content((0, 0), text("0", size: 3mm))
+ let t = content((0, 0), text("1", size: 3mm))
+ cetz.canvas(cetz_snake(depth, b, t))
+};