diff --git a/mergesort.c b/mergesort.c
index 1185267936d027adfd879e9b911594de9b576f6f..aa92d02bf52c65240e7af8209e4d772acb6500a1 100644
--- a/mergesort.c
+++ b/mergesort.c
@@ -1,91 +1,104 @@
 #include <stdlib.h>
+#include <string.h>
 #include <mpi.h>
 #include <stdio.h>
 
-void merge(int* arr, int l, int m, int r, int* tmp) 
+void merge(int* arr1, int* arr2, int size1, int size2)
 {
-  int last = l;
+  int *tmp = (int*) malloc(sizeof(int) * (size1 + size2));
+  int last = 0;
 
   // merge to tmp
-  int i = l, j = m;
-  for (; i < m && j < r;)
+  int i = 0, j = 0;
+  for (; i < size1 && j < size2;)
   {
-    if (arr[i] > arr[j])
-      tmp[last++] = arr[j++];
+    if (arr1[i] > arr2[j])
+      tmp[last++] = arr2[j++];
     else
-      tmp[last++] = arr[i++];
+      tmp[last++] = arr1[i++];
   }
-  while (i < m) tmp[last++] = arr[i++];
-  while (j < r) tmp[last++] = arr[j++];
+  while (i < size1) tmp[last++] = arr1[i++];
+  while (j < size2) tmp[last++] = arr2[j++];
 
   // move to origin
-  while (last > l) 
+  for(int i = 0; i < last; ++i)
   {
-    --last;
-    arr[last] = tmp[last];
+    arr1[i] = tmp[i];
   }
+
+  free(tmp);
 }
 
-void mergesort(int* arr, int l, int r, int* tmp) 
+void mergesort(int* arr, int l, int r) 
 {
   if (l + 2 > r) return;      // base
 
   int m = (l + r) >> 1;
-  mergesort(arr, l, m, tmp);
-  mergesort(arr, m, r, tmp);
-  merge(arr, l, m, r, tmp);
+  mergesort(arr, l, m);
+  mergesort(arr, m, r);
+  merge(arr+l, arr+m, m-l, r-m);
 }
 
 int main(int argc, char *argv[])
 {
-  int n, i;
-  scanf("%d", &n);
-
-  int *arr = (int*) malloc(sizeof(int) * (n + 1));
-  for (i = 0; i < n; ++i)
-  {
-    scanf("%d", &arr[i]);
-  }
-
+  int n = 0, i;
+  
   int world_rank;
   int world_size;
-  
+
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
 
-  int size = n / world_size;          // equally distributed
-  
-  int *arr_part = (int*) malloc(sizeof(int) * size);
-  MPI_Scatter(arr, size, MPI_INT, arr_part, size, MPI_INT, 0, MPI_COMM_WORLD);    // scatter to buckets
-  
-  int *tmp = (int*) malloc(sizeof(int) * size);
-  mergesort(arr_part, 0, size, tmp);
-  
-  int *sorted = NULL;
-  if(world_rank == 0) {
-    sorted = malloc(n * sizeof(int));
+  if (!world_rank) scanf("%d", &n);
+  int size = (n + world_size - 1) / world_size;          // equally distributed
+  int N = size * world_size;
+
+  int *arr = (int*) malloc(sizeof(int) * N);
+  memset(arr, 127, sizeof(int) * N);
+  if (!world_rank) {
+    for (i = 0; i < n; ++i) scanf("%d", &arr[i]);
+  }
+
+  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
+
+  mergesort(arr, 0, size);
+
+  int x = 1;
+  MPI_Status stat;
+  char isSend = 0;
+  while (x < world_size) 
+  {
+    if (world_rank & x == x)
+    {
+      MPI_Send(arr, size, MPI_INT, world_rank + x, 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;
+    }
+
+    x <<= 1;
   }
   
-  MPI_Gather(arr_part, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD);    // gather result
-  
-  if(world_rank == 0) 
+  if (world_rank == world_size)
   {    
-    int *tmp2 = (int*) malloc(sizeof(int) * n);
-    mergesort(sorted, 0, n, tmp2);
-
     for(i = 0; i < n; i++) 
     {      
-      printf("%d ", sorted[i]);
-    }
+      printf("%d ", arr[i]);
+    } 
+    puts("");
       
-    free(sorted);
-    free(tmp2);
   }
-
   free(arr);
-  free(arr_part);
-  free(tmp);
 
   MPI_Barrier(MPI_COMM_WORLD);
   MPI_Finalize();
diff --git a/mpi_hostfile b/mpi_hostfile
index 2441373bc37c202811a0d4e4ba0d6124963703a6..068dea3a6b768e124ad7389e57cb1e45f1724cc7 100644
--- a/mpi_hostfile
+++ b/mpi_hostfile
@@ -1,9 +1,9 @@
 #daftar host 
 localhost 
 #167.205.35.26 
-167.205.35.28 
-167.205.35.29 
-167.205.35.30 
+#167.205.35.28 
+#167.205.35.29 
+#167.205.35.30 
 #167.205.35.31 
 #167.205.35.32 
 #167.205.35.33 
diff --git a/sort b/sort
index 21dd03803e7224f096748d72f4f26a482cdc5cd7..65828fb6fe8ce8d368ef1f1eb2c57df82c1ced10 100755
Binary files a/sort and b/sort differ