diff --git a/mergesort.c b/mergesort.c
index aa92d02bf52c65240e7af8209e4d772acb6500a1..2830b462a55935bad3a0d6985272e1d78c006f94 100644
--- a/mergesort.c
+++ b/mergesort.c
@@ -51,6 +51,8 @@ int main(int argc, char *argv[])
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
 
   if (!world_rank) scanf("%d", &n);
+  MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);  
+
   int size = (n + world_size - 1) / world_size;          // equally distributed
   int N = size * world_size;
 
@@ -61,7 +63,6 @@ int main(int argc, char *argv[])
   }
 
   world_rank++;   // 1-based
-  MPI_Bcast(&size, 1, MPI_INT, 0, MPI_COMM_WORLD);  
   MPI_Scatter(arr, size, MPI_INT, 
               arr, size, MPI_INT, 
               0, MPI_COMM_WORLD);    // scatter to buckets
@@ -73,17 +74,17 @@ int main(int argc, char *argv[])
   char isSend = 0;
   while (x < world_size) 
   {
-    if (world_rank & x == x)
+    if ((-world_rank & world_rank & x) == x)
     {
-      MPI_Send(arr, size, MPI_INT, world_rank + x, world_rank + x, MPI_COMM_WORLD);
+      MPI_Send(arr, size, MPI_INT, world_rank + x - 1, world_rank + x, MPI_COMM_WORLD);
       isSend = 1;
     } else 
     {
-      if (isSend) continue;
-
-      MPI_Recv(arr, size, MPI_INT, world_rank + x, world_rank + x, MPI_COMM_WORLD, &stat);
-      merge(arr, arr+size, size, size);
-      size <<= 1;
+      if (!isSend) {
+        MPI_Recv(arr+size, size, MPI_INT, world_rank - x - 1, world_rank, MPI_COMM_WORLD, &stat);
+        merge(arr, arr+size, size, size);
+        size <<= 1;
+      }
     }
 
     x <<= 1;
@@ -95,8 +96,6 @@ int main(int argc, char *argv[])
     {      
       printf("%d ", arr[i]);
     } 
-    puts("");
-      
   }
   free(arr);