diff --git a/src/fof.c b/src/fof.c
index 3b60abbccf51a2ad80ad5d814a815aca90f684af..92090f84fa9f12e8ee18234df9be0c305b5d0e71 100644
--- a/src/fof.c
+++ b/src/fof.c
@@ -375,6 +375,7 @@ void fof_search_cell(struct space *s, struct cell *c) {
   struct gpart *gparts = c->gparts;
   const double l_x2 = s->l_x2;
   int *group_index = s->fof_data.group_index;
+  //long long *group_id = s->fof_data.group_id;
 
   /* Make a list of particle offsets into the global gparts array. */
   int *const offset = group_index + (ptrdiff_t)(gparts - s->gparts);
@@ -416,13 +417,17 @@ void fof_search_cell(struct space *s, struct cell *c) {
 
         /* 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 to root to point to pi's.*/
+        //if (group_id[root_j - node_offset] < group_id[root_i - node_offset]) {
         if (root_j < root_i) {
           atomic_min(&group_index[root_i - node_offset], root_j);
           /* Update root_i on the fly. */
           root_i = root_j;
+          //group_id[root_i - node_offset] = group_id[root_j - node_offset];
         }
-        else
+        else {
           atomic_min(&group_index[root_j - node_offset], root_i);
+          //group_id[root_j - node_offset] = group_id[root_i - node_offset];
+        }
 
       }
     }
@@ -439,6 +444,7 @@ void fof_search_pair_cells(struct space *s, struct cell *ci, struct cell *cj) {
   const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
   const double l_x2 = s->l_x2;
   int *group_index = s->fof_data.group_index;
+  //long long *group_id = s->fof_data.group_id;
   
   /* Make a list of particle offsets into the global gparts array. */
   int *const offset_i = group_index + (ptrdiff_t)(gparts_i - s->gparts);
@@ -499,13 +505,17 @@ void fof_search_pair_cells(struct space *s, struct cell *ci, struct cell *cj) {
 
         /* 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 to root to point to pi's.*/
+        //if (group_id[root_j - node_offset] < group_id[root_i - node_offset]) {
         if (root_j < root_i) {
           atomic_min(&group_index[root_i - node_offset], root_j);
           /* Update root_i on the fly. */
           root_i = root_j;
+          //group_id[root_i - node_offset] = group_id[root_j - node_offset];
         }
-        else
+        else {
           atomic_min(&group_index[root_j - node_offset], root_i);
+          //group_id[root_j - node_offset] = group_id[root_i - node_offset];
+        }
 
       }
     }
@@ -587,7 +597,7 @@ void fof_search_pair_cells_foreign(struct space *s, struct cell *ci, struct cell
         if (r2 < l_x2) {
 
           /* Store the particle IDs and group ID for communication. */
-          //fof_send[send_count].local_pid = pi->id_or_neg_offset;        
+          fof_send[*send_count].local_pid = pi->id_or_neg_offset;        
           fof_send[*send_count].foreign_pid = pj->id_or_neg_offset;        
           fof_send[*send_count].root_i = root_i;
           (*send_count)++;
@@ -644,7 +654,7 @@ void fof_search_pair_cells_foreign(struct space *s, struct cell *ci, struct cell
         if (r2 < l_x2) {
 
           /* Store the particle IDs and group ID for communication. */
-          //fof_send[send_count].local_pid = pi->id_or_neg_offset;        
+          fof_send[*send_count].local_pid = pi->id_or_neg_offset;        
           fof_send[*send_count].foreign_pid = pi->id_or_neg_offset; 
           fof_send[*send_count].root_i = root_j;
           (*send_count)++;
@@ -1017,10 +1027,37 @@ void fof_search_foreign_cells(struct space *s) {
 
   message("Rank: %d Searching received links....", engine_rank);
 
-  if(engine_rank != 0) {
+  int found_count = 0;
+  int link_count = 0;
+  int double_link_count = 0;
+
+  if(engine_rank == 0) {
+    
+    MPI_Status stat1, stat2;
+    MPI_Recv(&send_count, 1, MPI_INT, 1, MPI_RANK_1_SEND_TAG, MPI_COMM_WORLD, &stat1);
+    MPI_Recv(fof_recv, send_count, fof_mpi_type, 1, MPI_RANK_1_SEND_TAG, MPI_COMM_WORLD, &stat2);
+
+    for(int i=0; i<send_count; i++ ) {
+ 
+      int local_root = fof_find(fof_recv[i].foreign_pid - node_offset, s->fof_data.group_index);
+
+      //if(local_root == fof_recv[i].root_i) continue;
+
+      if(fof_recv[i].root_i < local_root) {
+   
+        s->fof_data.group_index[local_root - node_offset] = fof_recv[i].root_i;
+
+        //message("Rank: %d Particle %lld found new group with root: %d, previous group: %d, i=%d, j=%d, k=%d", engine_rank, gp->id_or_neg_offset, fof_recv[i].root_i, local_root, i,j,k);
+
+        link_count++;
+
+      }
+
+    }
+    message("Send count: %zu, found count: %d, link count: %d, double link count: %d", send_count, found_count, link_count, double_link_count);
+  }
 
-    int found_count = 0;
-    int link_count = 0;
+  if(engine_rank != 0) {
 
     for(int i=0; i<send_count; i++ ) {
 
@@ -1050,28 +1087,48 @@ void fof_search_foreign_cells(struct space *s) {
 
             if(fof_recv[i].root_i < local_root) {
 
-              s->fof_data.group_index[local_root - node_offset] = fof_recv[i].root_i;
+              if(local_root < node_offset) {
+                //message("Already linked to group on lower rank. Need to link to new lower root on other rank. Current root: %d, new root on lower rank: %d", local_root, fof_recv[i].root_i);
+
+                fof_send[double_link_count].foreign_pid = local_root;
+                fof_send[double_link_count].root_i = fof_recv[i].root_i;
+
+                double_link_count++;
+              }
+              else {
+
+                s->fof_data.group_index[local_root - node_offset] = fof_recv[i].root_i;
+
+                //message("Rank: %d Particle %lld found new group with root: %d, previous group: %d, i=%d, j=%d, k=%d", engine_rank, gp->id_or_neg_offset, fof_recv[i].root_i, local_root, i,j,k);
 
-              //message("Rank: %d Particle %lld found new group with root: %d, previous group: %d, i=%d, j=%d, k=%d", engine_rank, gp->id_or_neg_offset, fof_recv[i].root_i, local_root, i,j,k);
-              
-              link_count++;
+                link_count++;
+                
+                if(s->fof_data.group_index[local_root - node_offset] >= node_offset) {
+                  error("Particle not linked to rank 0. root still: %d, local_root: %d, fof_recv[%d].root_i: %d", s->fof_data.group_index[local_root - node_offset], local_root, i, fof_recv[i].root_i);
+                }
+              }
             }
-            
+
             break;
           }
 
         }
         if(found == 1) break;
       }
-        
+
       if(found == 0) error("Rank: %d could not find particle locally. PID: %lld", engine_rank, fof_recv[i].foreign_pid);
-      
-    }
 
-    message("Send count: %zu, found count: %d, link count: %d", send_count, found_count, link_count);
+    }
 
   }
-  
+
+    message("Send count: %zu, found count: %d, link count: %d, double link count: %d", send_count, found_count, link_count, double_link_count);
+
+    if(engine_rank == 1) {
+      MPI_Send(&double_link_count, 1, MPI_INT, 0, MPI_RANK_1_SEND_TAG, MPI_COMM_WORLD);
+      MPI_Send(fof_send, double_link_count, fof_mpi_type, 0, MPI_RANK_1_SEND_TAG, MPI_COMM_WORLD);
+    }
+
   message("Rank: %d Finished searching received links....", engine_rank);
 
   fclose(fof_file);
@@ -1227,6 +1284,15 @@ void fof_search_tree(struct space *s) {
     }
 
   }
+#else
+  fof_file = fopen("serial_group_index.dat", "w");
+  fprintf(fof_file, "# %7s %7s\n", "Index", "Group ID");
+  fprintf(fof_file, "#-------------------------------\n");
+
+  for (size_t i = 0; i < nr_gparts; i++) {
+
+    fprintf(fof_file, "  %7zu %7d \n", i, group_index[i]);
+  }
 #endif /* WITH_MPI */
 
   int num_parts_in_groups = 0;
diff --git a/src/fof.h b/src/fof.h
index 74c211fc3f833d50dae9675f6a025c26f58004a4..50d1edaf0ca171d999df4a1608a4fd719e82e2aa 100644
--- a/src/fof.h
+++ b/src/fof.h
@@ -31,7 +31,7 @@
 struct fof_mpi {
   
   /* The local particle ID of the sending rank.*/
-  //long long local_pid;
+  long long local_pid;
 
   /* The foreign particle ID of the receiving rank.*/
   long long foreign_pid;