diff --git a/src/main.rs b/src/main.rs
index 5673df18ea838cb4b125d2a9481a28930ff0a681..c8cec4c23213174d696d46c7853ed1bc4fefd153 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -46,15 +46,15 @@ fn main() -> std::io::Result<()> {
     let mut cocycle_differential_graph_edge_orbits: Vec<Vec<usize>> = vec![];
 
     // NOTE: Start with the normal form of the wheel graph.
-    let wheel_graph: UndirectedGraph = UndirectedGraph::wheel_graph(num_spokes);
-    let (wheel_graph_sign, wheel_graph_normal, wheel_graph_vertex_orbits, _) =
+    let mut wheel_graph: UndirectedGraph = UndirectedGraph::wheel_graph(num_spokes);
+    let (wheel_graph_sign, wheel_graph_vertex_orbits, _) =
         wheel_graph.normal_form(false);
     if wheel_graph_sign == 0 {
         eprintln!("The {}-wheel graph has an automorphism that induces an odd permutation on edges, so it is equal to zero in the graph complex.", num_spokes);
         process::exit(1);
     }
-    cocycle_graphs.push(wheel_graph_normal.clone());
-    cocycle_graph_index.insert(wheel_graph_normal.clone(), 0);
+    cocycle_graphs.push(wheel_graph.clone());
+    cocycle_graph_index.insert(wheel_graph, 0);
     cocycle_graph_vertex_orbits.push(wheel_graph_vertex_orbits);
 
     // Write a placeholder for the header.
diff --git a/src/undirected_graph.rs b/src/undirected_graph.rs
index 4e06b91c392d77f27e8e9ce4aaa308bef948a3b3..b78a280d95b4b748f580625ef59483d7d74e330d 100644
--- a/src/undirected_graph.rs
+++ b/src/undirected_graph.rs
@@ -83,20 +83,6 @@ impl UndirectedGraph {
         UndirectedGraph::new(num_spokes + 1, wheel_edges)
     }
 
-    pub fn from_nauty(nauty_graph: &[u64]) -> UndirectedGraph {
-        // Number of edges = (sum of vertex degrees) / 2.
-        let num_edges: usize = nauty_graph
-            .iter()
-            .map(|&setword| setword.count_ones() as usize)
-            .sum::<usize>()
-            >> 1;
-        UndirectedGraph {
-            num_vertices: nauty_graph.len(),
-            num_edges,
-            nauty_graph: nauty_graph.to_vec(),
-        }
-    }
-
     fn induced_edge_permutation(
         g: &UndirectedGraph,
         h: &UndirectedGraph,
@@ -201,9 +187,9 @@ impl UndirectedGraph {
     }
 
     pub fn normal_form(
-        &self,
+        &mut self,
         compute_edge_orbits: bool,
-    ) -> (i32, UndirectedGraph, HashMap<usize, usize>, Vec<usize>) {
+    ) -> (i32, HashMap<usize, usize>, Vec<usize>) {
         let mut options: nauty_Traces_sys::optionblk = nauty_Traces_sys::optionblk {
             getcanon: nauty_Traces_sys::TRUE,
             userautomproc: Some(Self::process_nauty_automorphism),
@@ -229,7 +215,7 @@ impl UndirectedGraph {
 
         unsafe {
             nauty_Traces_sys::densenauty(
-                self.nauty_graph.clone().as_mut_ptr(), // TODO: Remove this clone...
+                self.nauty_graph.as_mut_ptr(),
                 lab.as_mut_ptr(),
                 ptn.as_mut_ptr(),
                 orbits.as_mut_ptr(),
@@ -241,7 +227,12 @@ impl UndirectedGraph {
             );
         }
 
-        let normal_self: UndirectedGraph = Self::from_nauty(&normal_graph);
+        // TODO: Avoid the extra struct here?
+        let normal_self: UndirectedGraph = UndirectedGraph {
+            num_vertices: self.num_vertices,
+            num_edges: self.num_edges,
+            nauty_graph: normal_graph
+        };
 
         // NOTE: The map k -> lab[k] relabels normal_self to self, so we need the inverse to get the orbits in normal_self.
         let mut lab_inv: Vec<i32> = vec![0; n];
@@ -282,12 +273,9 @@ impl UndirectedGraph {
             }
         });
 
-        (
-            sign,
-            normal_self,
-            normal_self_orbits,
-            normal_self_edge_orbits,
-        )
+        self.nauty_graph = normal_self.nauty_graph;
+
+        (sign, normal_self_orbits, normal_self_edge_orbits)
     }
 
     fn expand_vertex(&self, &position: &usize) -> Vec<(i64, UndirectedGraph)> {
@@ -425,19 +413,19 @@ impl UndirectedGraph {
         let mut diff: HashMap<UndirectedGraph, (i64, Vec<usize>)> = HashMap::new();
 
         for (&orbit_rep, &orbit_size) in orbits {
-            for (c, dg) in self.expand_vertex(&orbit_rep) {
+            for (c, mut dg) in self.expand_vertex(&orbit_rep) {
                 // TODO: Avoid computing orbits when not used.
-                let (normal_dg_sign, normal_dg, _normal_dg_orbits, normal_dg_edge_orbits) =
+                let (normal_dg_sign, _normal_dg_orbits, normal_dg_edge_orbits) =
                     dg.normal_form(true);
                 if normal_dg_sign == 0 {
                     continue;
                 }
                 // TODO: Fix coefficient types.
                 let normal_dg_coeff: i64 = (normal_dg_sign as i64) * (orbit_size as i64) * c;
-                if let Some((diff_coeff, _)) = diff.get_mut(&normal_dg) {
+                if let Some((diff_coeff, _)) = diff.get_mut(&dg) {
                     *diff_coeff += normal_dg_coeff;
                 } else {
-                    diff.insert(normal_dg, (normal_dg_coeff, normal_dg_edge_orbits));
+                    diff.insert(dg, (normal_dg_coeff, normal_dg_edge_orbits));
                 }
             }
         }
@@ -518,18 +506,18 @@ impl UndirectedGraph {
                 continue;
             }
 
-            let cg: UndirectedGraph = UndirectedGraph {
+            let mut cg: UndirectedGraph = UndirectedGraph {
                 num_vertices: self.num_vertices - 1,
                 num_edges: self.num_edges - 1,
                 nauty_graph: contracted_graph,
             };
 
-            let (normal_cg_sign, normal_cg, normal_cg_orbits, _) = cg.normal_form(false);
+            let (normal_cg_sign, normal_cg_orbits, _) = cg.normal_form(false);
             if normal_cg_sign == 0 {
                 continue;
             }
 
-            contractions.insert(normal_cg, normal_cg_orbits);
+            contractions.insert(cg, normal_cg_orbits);
         }
         contractions
     }