diff --git a/README.md b/README.md
index be3ec3d19adb0e4a4f944cd054c2f340f43c838c..b37351a0554d7595b89f5ef804cfd9b2acbb0391 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,27 @@ Minimum Spanning Tree merupakan suatu tree yang memiliki bobot minimum yang meng
 
 Untuk meningkatkan eksekusi pembangunan tree, maka kami memanfaatkan OpenMP dan OpenMPI sebagai library pemrograman paralel untuk kasus dengan jumlah node > 1000.
 
+## Logika Cara Paralel
+<h4>OpenMP</h4>
+OpenMP adalah standar yang kita digunakan untuk melakukan pemrograman paralel multithreading pada arsitektur shared memory. Termasuk pada compiler GCC, sehingga tidak perlu instalasi tambahan. Kompilasi program menggunakan gcc -fopenmp dan menggunakan library "omp.h".
+<br><br>
+Langkah yang dilakukan adalah dengan menggunakan #pragma omp parallel for untuk melakukan paralel pada instruksi for. Hal ini kami lakukan saat membentuk V subset inisialisasi dengan wight 0 dan parent adalah i. Selain itu kami juga melakukan omp parallel for untuk penghitungan minimum cost dari tree yang dibangun. Kami juga menggunakan #pragma omp critical untuk bagian yang tidak bisa dilakukan bersamaan saat proses paralel.
+<br><br>
+Selain itu kami juga menggunakan #pragma omp task untuk melakukan paralelisasi terhadap 2 buah instruksi rekursif saat melakukan quick sort yang dibungkus dengan #pragma omp single dan dibungkus dengan #pragma omp parallel
+<br><br>
+Kami juga memberikan alternatif memparalelkan bubble sort (ada di program namun tidak digunakan) dengan menggunakan #pragma omp parallel for dan mencegah critical section dengan #pragma omp critical. Namun karena hasil eksekusi lebih cepat menggunakan quick sort yang telah diparalelkan, maka kita tidak menggunakan bubble sort.
+
+<br><br>
+<h4>OpenMPI</h4>
+Algoritma MST yang digunakan adalah Algoritma Kruskall, dimana dalam proses pembuatannya perlu dilakukan pengurutan edge-edge terlebih dahulu dari yang terkecil hingga yang terbesar. Kemudian edge-edge yang akan dipilih dimulai dari edge terkecil dan dijamin tidak menyebabkan adanya loop dalam tree tersebut. OpenMPI sendiri merupakan teknik paralelisasi dengan memanfaatkan distributed memory dimana proses besar dipecah menjadi proses kecil-kecil yang akan dieksekusi di setiap memory. MPI sendiri berarti message passing interface yang akan mengirimkan message dari memory kecil ke memory utama yang akan menggabungkan kumpulan proses kecil itu sendiri.
+<br><br>
+Dalam algoritma MST, ide paralelisasi kami terapkan pada pengurutan edge, dimana cukup memegang kunci di dalam algoritma MST ini sendiri. Algoritma pengurutan yang digunakan adalah Quick Sort. Ide paralelisasi Quick Sort secara umum adalah sebagai berikut.
+1. Lakukan partisi suatu array of edges pada pivot tertentu sehingga terbentuk kumpulan nilai yang lebih kecil dan lebih besar dari pivot
+2. Subarray dengan ukuran lebih besar akan direkursifkan kembali, sedangkan subarray yang lebih kecil akan diberikan kepada proses lain.
+3. Diterapkan mekanisme untuk Send and Receive dimana proses lain akan menerima subarray dari proses sourcenya dan mengembalikan subarray terurut kepada proses sourcenya ini sendiri.
+4. Semua subarray yang sudah terurut akan dikembalikan ke source process terus menerus sampai menuju ke root process.
+<br>
+
 ## How to Run
 Pertama pastikan adnda berada pada bagian home (bukan pada folder src dan folder test) <br><br>
 ```
@@ -14,6 +35,7 @@ gcc -o MST_OpenMP MST_OpenMP.c
 
 ```
 <br>
+
 ```
 
 Cara menjalankan program OpenMP:
@@ -23,14 +45,4 @@ Cara menjalankan program OpenMP:
 
 ## Author
 * Michael Hans / 13518056
-* Kevin Austin Stefano / 13518104
-
-
-## Paralelisasi menggunakan OpenMPI
-Algoritma MST yang digunakan adalah Algoritma Kruskall, dimana dalam proses pembuatannya perlu dilakukan pengurutan edge-edge terlebih dahulu dari yang terkecil hingga yang terbesar. Kemudian edge-edge yang akan dipilih dimulai dari edge terkecil dan dijamin tidak menyebabkan adanya loop dalam tree tersebut. OpenMPI sendiri merupakan teknik paralelisasi dengan memanfaatkan distributed memory dimana proses besar dipecah menjadi proses kecil-kecil yang akan dieksekusi di setiap memory. MPI sendiri berarti message passing interface yang akan mengirimkan message dari memory kecil ke memory utama yang akan menggabungkan kumpulan proses kecil itu sendiri.
-
-Dalam algoritma MST, ide paralelisasi kami terapkan pada pengurutan edge, dimana cukup memegang kunci di dalam algoritma MST ini sendiri. Algoritma pengurutan yang digunakan adalah Quick Sort. Ide paralelisasi Quick Sort secara umum adalah sebagai berikut.
-1. Lakukan partisi suatu array of edges pada pivot tertentu sehingga terbentuk kumpulan nilai yang lebih kecil dan lebih besar dari pivot
-2. Subarray dengan ukuran lebih besar akan direkursifkan kembali, sedangkan subarray yang lebih kecil akan diberikan kepada proses lain.
-3. Diterapkan mekanisme untuk Send and Receive dimana proses lain akan menerima subarray dari proses sourcenya dan mengembalikan subarray terurut kepada proses sourcenya ini sendiri.
-4. Semua subarray yang sudah terurut akan dikembalikan ke source process terus menerus sampai menuju ke root process.
\ No newline at end of file
+* Kevin Austin Stefano / 13518104
\ No newline at end of file
diff --git a/grade-openmp.sh b/grade-openmp.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bc424e3573e53e43e3aed47351eb3644d8f055c0
--- /dev/null
+++ b/grade-openmp.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+if [ "$#" -ne 2 ]; then
+    echo "Usage: ./autograde.sh <nim> <openmp_output_directory>"
+    exit
+fi
+
+rm -rf $2/*
+
+rm -rf ./tmp
+mkdir ./tmp
+mkdir ./tmp/testcases
+
+if ! python3 ./python_script/get_testcase.py $1; then
+    exit
+fi
+
+testcases_names=()
+
+readarray -d '' testcases_names < <(find ./tmp/testcases -type f -print0)
+
+for tc in ${testcases_names[@]}; do
+    ./openmp-script.sh $tc
+done
+
+if ! python3 ./python_script/check_openmp.py $1 $2; then
+    exit
+fi
+
+zip -r $1.zip .
+
+if ! python3 ./python_script/submit_file.py $1 $1.zip; then
+    exit
+fi
+echo "Thank you for using our service!"
diff --git a/grade-openmpi.sh b/grade-openmpi.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6e71e021f1d80007dd16bd7ef2c1f65c73cd99cb
--- /dev/null
+++ b/grade-openmpi.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+if [ "$#" -ne 2 ]; then
+    echo "Usage: ./autograde.sh <nim> <openmpi_output_directory>"
+    exit
+fi
+
+rm -rf $2/*
+
+rm -rf ./tmp
+mkdir ./tmp
+mkdir ./tmp/testcases
+
+if ! python3 ./python_script/get_testcase.py $1; then
+    exit
+fi
+
+testcases_names=()
+
+readarray -d '' testcases_names < <(find ./tmp/testcases -type f -print0)
+
+for tc in ${testcases_names[@]}; do
+    ./openmpi-script.sh $tc
+done
+
+if ! python3 ./python_script/check_openmpi.py $1 $2; then
+    exit
+fi
+
+zip -r $1.zip .
+
+if ! python3 ./python_script/submit_file.py $1 $1.zip then
+    exit
+fi
+echo "Thank you for using our service!"
diff --git a/hostname b/hostname
new file mode 100644
index 0000000000000000000000000000000000000000..92d4a1958953b6e45f81deeb148867766838186b
--- /dev/null
+++ b/hostname
@@ -0,0 +1,5 @@
+172.31.65.212
+172.31.79.254
+172.31.68.110
+172.31.79.57
+172.31.75.79s
diff --git a/openmp-script.sh b/openmp-script.sh
new file mode 100755
index 0000000000000000000000000000000000000000..104c1ade050f2fbe283784a5f0056951dd5680cc
--- /dev/null
+++ b/openmp-script.sh
@@ -0,0 +1,11 @@
+if [ "$#" -ne 1 ]; then
+    echo 'Usage: ./openmp-script.sh <input_file>'
+    exit
+fi
+
+input=$1
+filename=`basename $1`
+
+cat $1 | ./src/MST_OpenMP > output_mp/tmp
+sed '$d' output_mp/tmp > output_mp/$filename
+rm -f output_mp/tmp
diff --git a/openmpi-script.sh b/openmpi-script.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8e394d96fe5cc9df537f6f71b22303ca7879a824
--- /dev/null
+++ b/openmpi-script.sh
@@ -0,0 +1,12 @@
+if [ "$#" -ne 1 ]; then
+    echo 'Usage: ./openmpi-script.sh <input_file>'
+    exit
+fi
+
+input=$1
+filename=`basename $1`
+
+cat $1 | mpirun --hostfile hostname -np 5 ./src/MST_OpenMPI < $input > output_mpi/tmp
+sed '$d' output_mpi/tmp > output_mpi/$filename
+
+rm -f output_mpi/tmp
\ No newline at end of file
diff --git a/output_mp/test_5 b/output_mp/test_5
new file mode 100644
index 0000000000000000000000000000000000000000..2734eef50f4aaad6b790f549ad5e2b729c8cdcdc
--- /dev/null
+++ b/output_mp/test_5
@@ -0,0 +1,4 @@
+5
+0-1
+1-3
+2-4
diff --git a/python_script/check_openmp.py b/python_script/check_openmp.py
new file mode 100644
index 0000000000000000000000000000000000000000..7021a046a7a5b88b5a61c2ae05ea4e58d9951396
--- /dev/null
+++ b/python_script/check_openmp.py
@@ -0,0 +1,43 @@
+import os
+import sys
+import requests
+
+from os import walk
+
+nim = sys.argv[1]
+openmp_dir = sys.argv[2]
+
+url = 'http://100.25.13.77/api/v1/check'
+
+body = {
+    'nim': nim,
+    'is_openmp': True,
+    'answers': [],
+}
+
+_, _, openmp_files = next(walk(openmp_dir))
+
+for file in openmp_files:
+    total_node = file.split('_')[0]
+    testcase_id = file.split('_')[1]
+    f = open(os.path.join(openmp_dir, file), 'r')
+    content = f.read()
+    f.close()
+    answer = {
+        'total_node': int(total_node),
+        'testcase_id': int(testcase_id),
+        'answer': content,
+    }
+    body['answers'].append(answer)
+
+response = requests.post(url = url, json = body)
+
+print('OpenMP Status Code:', response.status_code)
+if response.status_code != 200:
+    sys.exit(-1)
+else:
+    data = response.json()
+    results = data['results']
+    for result in results:
+        print('Total Node:', result['total_node'])
+        print('Correct:', result['is_accepted'])
diff --git a/python_script/check_openmpi.py b/python_script/check_openmpi.py
new file mode 100644
index 0000000000000000000000000000000000000000..d484f396f8d12ff7853b352f8d092b1e5fa64f1d
--- /dev/null
+++ b/python_script/check_openmpi.py
@@ -0,0 +1,43 @@
+import os
+import sys
+import requests
+
+from os import walk
+
+nim = sys.argv[1]
+openmpi_dir = sys.argv[2]
+
+url = 'http://100.25.13.77/api/v1/check'
+
+body = {
+    'nim': nim,
+    'is_openmp': False,
+    'answers': [],
+}
+
+_, _, openmpi_files = next(walk(openmpi_dir))
+
+for file in openmpi_files:
+    total_node = file.split('_')[0]
+    testcase_id = file.split('_')[1]
+    f = open(os.path.join(openmpi_dir, file), 'r')
+    content = f.read()
+    f.close()
+    answer = {
+        'total_node': int(total_node),
+        'testcase_id': int(testcase_id),
+        'answer': content,
+    }
+    body['answers'].append(answer)
+
+response = requests.post(url = url, json = body)
+
+print('OpenMPI Status Code:', response.status_code)
+if response.status_code != 200:
+    sys.exit(-1)
+else:
+    data = response.json()
+    results = data['results']
+    for result in results:
+        print('Total Node:', result['total_node'])
+        print('Correct:', result['is_accepted'])
diff --git a/python_script/get_testcase.py b/python_script/get_testcase.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec6c763b9e1daf418a1b765d46857dfdc4c9b65b
--- /dev/null
+++ b/python_script/get_testcase.py
@@ -0,0 +1,24 @@
+import os
+import sys
+import requests
+
+nim = sys.argv[1]
+
+url = 'http://100.25.13.77/api/v1/testcase'
+
+params = {
+    'nim': nim,
+}
+
+response = requests.get(url = url, params = params)
+
+data = response.json()
+
+for tc in data['set']:
+    total_node = tc['total_node']
+    tc_id = tc['testcase_id']
+    content = tc['question']
+    filename = str(total_node) + '_' + str(tc_id)
+    f = open(os.path.join('tmp', 'testcases', filename), 'w')
+    f.write(content)
+    f.close()
diff --git a/python_script/submit_file.py b/python_script/submit_file.py
new file mode 100644
index 0000000000000000000000000000000000000000..e7642114aec2429e3fa975c6d1b1873fa83f709f
--- /dev/null
+++ b/python_script/submit_file.py
@@ -0,0 +1,16 @@
+import os
+import sys
+import requests
+
+from os import walk
+
+nim = sys.argv[1]
+filename = sys.argv[2]
+
+url = 'http://100.25.13.77/api/v1/submit?nim={nim}'.format(nim = nim)
+files = {
+    'file': open(filename, 'rb')
+}
+
+response = requests.post(url = url, files = files)
+print('Submission Status Code: {statusCode}'.format(statusCode = response.status_code))
diff --git a/src/Graph_Generator b/src/Graph_Generator
new file mode 100755
index 0000000000000000000000000000000000000000..529f43a74c369fb3d8fffd04b4616d6de4d526d0
Binary files /dev/null and b/src/Graph_Generator differ
diff --git a/src/MST_OpenMP b/src/MST_OpenMP
new file mode 100755
index 0000000000000000000000000000000000000000..e0b67dca12c01308f91b2c159833bcec277f3b76
Binary files /dev/null and b/src/MST_OpenMP differ
diff --git a/src/MST_OpenMP.c b/src/MST_OpenMP.c
index 43a07c910a3a1cbf5f0f9bdf39f7228225054b21..4b4e65e68ee3dbdd42cd26dfabb1584e3bc0219f 100644
--- a/src/MST_OpenMP.c
+++ b/src/MST_OpenMP.c
@@ -62,6 +62,38 @@ void PartisiSrc(Edge T[], int i, int j, int *k)
         {
             q--;
         }
+
+        if (p < q)
+        {
+            Edge temp = T[p - 1];
+            T[p - 1] = T[q - 1];
+            T[q - 1] = temp;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+void PartisiDest(Edge T[], int i, int j, int *k)
+{
+    Edge pivot = T[i - 1];
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (T[p - 1].dest < pivot.dest && T[p - 1].src != pivot.src)
+        {
+            p++;
+        }
+        while (T[q - 1].dest > pivot.dest  && T[p - 1].src != pivot.src)
+        {
+            q--;
+        }
+
         if (p < q)
         {
             Edge temp = T[p - 1];
@@ -84,6 +116,9 @@ void QuickSortSrc(Edge T[], int i, int j)
     int k;
     if (i < j)
     {
+        
+        PartisiSrc(T, i, j, &k);
+        PartisiDest(T, i, j, &k);
         PartisiSrc(T, i, j, &k);
         #pragma omp task
         {QuickSortSrc(T, k + 1, j);}
@@ -324,7 +359,6 @@ void KruskalMST(Graph *graph, Edge result[], int *e)
             QuickSortSrc(result, 1, (*e));
         }
     }
-   
     return;
 }
 
diff --git a/src/MST_OpenMPI b/src/MST_OpenMPI
new file mode 100755
index 0000000000000000000000000000000000000000..b8d21e740d2d76f6fb897fba1617500d62afcc5c
Binary files /dev/null and b/src/MST_OpenMPI differ
diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c
index 4fb1a5df0c1fa9095dd0cb9a6b810fef8fd416a0..389281e780cd850f40e0fffda4ee8b1b2fc1f286 100644
--- a/src/MST_OpenMPI.c
+++ b/src/MST_OpenMPI.c
@@ -325,7 +325,7 @@ int main()
         t = MPI_Wtime() - t;
         printResult(result, e);
         // printf("Waktu Eksekusi: %f ms \n", (t * 1000));
-        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
+        // MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
  
     } else {
         MPI_Datatype mpi_edge_type;
@@ -348,13 +348,15 @@ int main()
         // Declare the array buffer to receive data from the source process
         Edge* temp = (Edge *) malloc (sizeof(Edge) *arrLength);
         source = MPI_Recv(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-        
+        printf("Process %d\n", rank);
         // Sort the received buffer with QuickSort
         QuickSort(temp, 1, arrLength, rank, size, idxcnt);
-
+        printf("Process %d\n", rank);
         // Send the sorted array back to the source process
         source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD);
-        // printf("Process %d\n", rank);
+        
+        // source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD);
+        printf("Process %d\n", rank);
         free(temp);
     }
     MPI_Finalize();
diff --git a/src/a.out b/src/a.out
deleted file mode 100755
index a12166f3a9741fc0d80c56e112715438905d86ec..0000000000000000000000000000000000000000
Binary files a/src/a.out and /dev/null differ
diff --git a/test/test_5 b/test/test_5
index f5623b7767b59f380fa4dbe28bf094d776bb3876..11413f8b93f44e960e110bf8011173c4f82e424d 100644
--- a/test/test_5
+++ b/test/test_5
@@ -1,6 +1,6 @@
 5
--1  2  6 -1 -1
- 2 -1  4  1 -1
- 6  4 -1 -1  1
--1  1 -1 -1  1
--1 -1  1  1 -1
\ No newline at end of file
+-1 3 6 7 -1 
+3 -1 3 -1 6 
+6 3 -1 -1 9 
+7 -1 -1 -1 -1 
+-1 6 9 -1 -1