diff --git a/src/fof.c b/src/fof.c
index 9f8c578a353c8cd9ffe366b0cf14c7daf2cc3be2..75236cdf501ab10d1d41d4cf72c26dca607ace20 100644
--- a/src/fof.c
+++ b/src/fof.c
@@ -194,8 +194,9 @@ __attribute__((always_inline)) INLINE static size_t update_root(
 
 }
 
-__attribute__((always_inline)) INLINE static void fof_union(size_t *root_i, const size_t root_j,
-                                                          size_t *group_index) {
+#ifdef UNION_BY_SIZE
+__attribute__((always_inline)) INLINE static void fof_union_by_size(size_t *root_i, const size_t root_j,
+                                                          size_t *group_index, size_t *group_size) {
 
   int result = 0;
 
@@ -207,30 +208,44 @@ __attribute__((always_inline)) INLINE static void fof_union(size_t *root_i, cons
     /* Skip particles in the same group. */
     if(root_i_new == root_j_new) return;
 
-    /* If the root ID of pj is lower than pi's root ID set pi's root to point to pj's. 
-     * Otherwise set pj's root to point to pi's.*/
-    if(root_j_new < root_i_new) {
+    const size_t size_i = group_size[root_i_new];
+    const size_t size_j = group_size[root_j_new];
+
+    /* If group_i is smaller than group_j set group_i's root to point to group_j's. 
+     * Otherwise set group_j's root to point to group_i's.*/
+    if(size_i < size_j) {
       
       /* Updates the root and checks that its value has not been changed since being read. */
       result = update_root(&group_index[root_i_new], root_j_new);
       
+      if(result) {
+        atomic_add(&group_size[root_j_new], size_i);
+        atomic_sub(&group_size[root_i_new], size_i);
+      }
+
       /* Update root_i on the fly. */
       *root_i = root_j_new;
+
     }
     else {
       
       /* Updates the root and checks that its value has not been changed since being read. */
       result = update_root(&group_index[root_j_new], root_i_new);
       
+      if(result) {
+        atomic_add(&group_size[root_i_new], size_j);
+        atomic_sub(&group_size[root_j_new], size_j);
+      }
+
       /* Update root_i on the fly. */
       *root_i = root_i_new;
+      
     }
   } while (result != 1);
 }
-
-#ifdef UNION_BY_SIZE
-__attribute__((always_inline)) INLINE static void fof_union_by_size(size_t *root_i, const size_t root_j,
-                                                          size_t *group_index, size_t *group_size) {
+#else
+__attribute__((always_inline)) INLINE static void fof_union(size_t *root_i, const size_t root_j,
+                                                          size_t *group_index) {
 
   int result = 0;
 
@@ -242,38 +257,23 @@ __attribute__((always_inline)) INLINE static void fof_union_by_size(size_t *root
     /* Skip particles in the same group. */
     if(root_i_new == root_j_new) return;
 
-    const size_t size_i = group_size[root_i_new];
-    const size_t size_j = group_size[root_j_new];
-
-    /* If group_i is smaller than group_j set group_i's root to point to group_j's. 
-     * Otherwise set group_j's root to point to group_i's.*/
-    if(size_i < size_j) {
+    /* If the root ID of pj is lower than pi's root ID set pi's root to point to pj's. 
+     * Otherwise set pj's root to point to pi's.*/
+    if(root_j_new < root_i_new) {
       
       /* Updates the root and checks that its value has not been changed since being read. */
       result = update_root(&group_index[root_i_new], root_j_new);
       
-      if(result) {
-        atomic_add(&group_size[root_j_new], size_i);
-        atomic_sub(&group_size[root_i_new], size_i);
-      }
-
       /* Update root_i on the fly. */
       *root_i = root_j_new;
-
     }
     else {
       
       /* Updates the root and checks that its value has not been changed since being read. */
       result = update_root(&group_index[root_j_new], root_i_new);
       
-      if(result) {
-        atomic_add(&group_size[root_i_new], size_j);
-        atomic_sub(&group_size[root_j_new], size_j);
-      }
-
       /* Update root_i on the fly. */
       *root_i = root_i_new;
-      
     }
   } while (result != 1);
 }
@@ -1122,6 +1122,17 @@ void fof_search_foreign_cells(struct space *s) {
   /* The value of which is an offset into global_group_id, which is the actual root. */
   for(int i=0; i<group_count; i++) global_group_index[i] = i;
 
+#ifdef UNION_BY_SIZE
+  /* Store the original group size before incrementing in the Union-Find. */
+  size_t *orig_global_group_size = NULL;
+  
+  if (posix_memalign((void**)&orig_global_group_size, SWIFT_STRUCT_ALIGNMENT,
+                      group_count  * sizeof(size_t)) != 0)
+    error("Error while allocating memory for the displacement in memory for the global group link list");
+
+  for(int i=0; i<group_count; i++) orig_global_group_size[i] = global_group_size[i];
+#endif
+
   /* Perform a union-find on the group links. */
   for(int i=0; i<global_group_link_count; i++) {
   
@@ -1150,9 +1161,24 @@ void fof_search_foreign_cells(struct space *s) {
     size_t group_i = global_group_id[root_i];
     size_t group_j = global_group_id[root_j];
 
+    if(group_i == group_j) continue;
+
     /* Update roots accordingly. */
+#ifdef UNION_BY_SIZE
+    size_t size_i = global_group_size[root_i];
+    size_t size_j = global_group_size[root_j];
+    if(size_i < size_j) {
+      global_group_index[root_i] = root_j;
+      global_group_size[root_j] += size_i;
+    }
+    else {
+      global_group_index[root_j] = root_i;
+      global_group_size[root_i] += size_j;
+    }
+#else
     if(group_j < group_i) global_group_index[root_i] = root_j;
     else global_group_index[root_j] = root_i;
+#endif
 
   }
   
@@ -1170,12 +1196,16 @@ void fof_search_foreign_cells(struct space *s) {
     /* If the group is local update its root and size. */
     if(is_local(group_id, nr_gparts) && new_root != group_id) {
         group_index[group_id - node_offset] = new_root;
-        group_size[group_id - node_offset] -= global_group_size[i];
+
         group_mass[group_id - node_offset] -= global_group_mass[i];
         group_CoM[group_id - node_offset].x -= global_group_CoM[i].x;
         group_CoM[group_id - node_offset].y -= global_group_CoM[i].y;
         group_CoM[group_id - node_offset].z -= global_group_CoM[i].z;
-
+#ifdef UNION_BY_SIZE
+        group_size[group_id - node_offset] -= orig_global_group_size[i];
+#else
+        group_size[group_id - node_offset] -= global_group_size[i];
+#endif
     }
      
     /* If the group linked to a local root update its size. */
@@ -1204,7 +1234,12 @@ void fof_search_foreign_cells(struct space *s) {
       group_CoM[new_root - node_offset].y += (CoM_y * global_group_mass[i]);
       group_CoM[new_root - node_offset].z += (CoM_z * global_group_mass[i]);
 
+#ifdef UNION_BY_SIZE
+      /* Use group sizes before Union-Find */
+      group_size[new_root - node_offset] += orig_global_group_size[i];
+#else
       group_size[new_root - node_offset] += global_group_size[i];
+#endif
       group_mass[new_root - node_offset] += global_group_mass[i];
     }
 
@@ -1219,6 +1254,9 @@ void fof_search_foreign_cells(struct space *s) {
   free(global_group_size);
   free(global_group_mass);
   free(global_group_id);
+#ifdef UNION_BY_SIZE
+  free(orig_global_group_size);
+#endif
 
   message("Rank %d finished linking local roots to foreign roots.", engine_rank);
 
@@ -1404,7 +1442,7 @@ void fof_search_tree(struct space *s) {
   }
 
   size_t *local_roots = NULL;
-  int local_group_count = 0;
+  size_t local_group_count = 0;
 
   if (posix_memalign((void **)&local_roots, 32, num_local_roots * sizeof(size_t)) != 0)
     error("Failed to allocate list of local roots.");
@@ -1573,15 +1611,11 @@ void fof_search_tree(struct space *s) {
     for (size_t i = 0; i < nr_gparts; i++) {
       size_t root = node_offset + i;
       size_t local_root = node_offset + i;
-      int foreign = 0;
 
       /* FOF find */
       while (root != group_index[root - node_offset]) {
         root = group_index[root - node_offset];
-        if (!is_local(root, nr_gparts)) {
-          foreign = 1;
-          break;
-        }
+        if (!is_local(root, nr_gparts)) break;
 
         /* Store local root before index becomes foreign. */
         local_root = root;
@@ -1595,6 +1629,7 @@ void fof_search_tree(struct space *s) {
     /* Clean up memory. */
     free(group_counts);
     free(displ);
+    free(local_roots);
 
   }
 #endif
@@ -1648,7 +1683,7 @@ void fof_dump_group_data(char *out_file, struct space *s, struct group_length *g
   struct fof_CoM *group_CoM = s->fof_data.group_CoM;
   const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
   
-  fprintf(file, "# %10s %8s %10s %12s %12s %12s %12s\n", "Index", "Group ID", "Group Size", "Group Mass", "x CoM", "y CoM", "z CoM");
+  fprintf(file, "# %8s %10s %12s %12s %12s %12s\n", "Group ID", "Group Size", "Group Mass", "x CoM", "y CoM", "z CoM");
   fprintf(file, "#--------------------------------------------------------------------------------\n");
 
   for (int i = 0; i < s->fof_data.num_groups; i++) {
@@ -1662,7 +1697,7 @@ void fof_dump_group_data(char *out_file, struct space *s, struct group_length *g
       const double CoM_y = box_wrap(group_CoM[group_offset - node_offset].y, 0., dim[1]);
       const double CoM_z = box_wrap(group_CoM[group_offset - node_offset].z, 0., dim[2]);
 
-      fprintf(file, "  %10zu %8zu %10zu %12e %12e %12e %12e\n", group_offset - node_offset, gparts[group_offset - node_offset].group_id, group_size[group_offset - node_offset], group_mass[group_offset - node_offset], CoM_x, CoM_y, CoM_z);
+      fprintf(file, "  %8zu %10zu %12e %12e %12e %12e\n", gparts[group_offset - node_offset].group_id, group_size[group_offset - node_offset], group_mass[group_offset - node_offset], CoM_x, CoM_y, CoM_z);
     }
   }