diff --git a/src/MST_OpenMP b/src/MST_OpenMP
deleted file mode 100755
index 31321e2fd1b102ccd7c68b1d6467c0d5478aa3f0..0000000000000000000000000000000000000000
Binary files a/src/MST_OpenMP and /dev/null differ
diff --git a/src/MST_OpenMP.c b/src/MST_OpenMP.c
index 6b8963f3136a2575f872cec58e7e58b7894ba95d..757d567f3cffdcd4e6796db0587833ede7bd2267 100644
--- a/src/MST_OpenMP.c
+++ b/src/MST_OpenMP.c
@@ -245,7 +245,7 @@ int main()
     int t = clock();
     KruskalMST(graph, result, &e);
     t = clock() - t;
-    printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000);
     printResult(result, e);
+    printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000);
     return 0;
 }
\ No newline at end of file
diff --git a/src/MST_OpenMP.out b/src/MST_OpenMP.out
deleted file mode 100755
index 81f11debdaf328022fa25db0eb3d50a202cea1f0..0000000000000000000000000000000000000000
Binary files a/src/MST_OpenMP.out and /dev/null differ
diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed877dbf584f19035e5b9c881c214da4960e1660
--- /dev/null
+++ b/src/MST_OpenMPI.c
@@ -0,0 +1,259 @@
+// IF3230 - Sistem Paralel dan Terdistribusi
+// Michael Hans / 13518056
+// Kevin Austin Stefano / 13518104
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <mpi.h>
+
+// Edge structure
+typedef struct
+{
+    int src;
+    int dest;
+    int weight;
+} Edge;
+
+// Graph structure
+typedef struct 
+{
+    int V; // number of vertices
+    int E; // number of edges
+    Edge *edge;
+} Graph;
+
+// Create new Graph based on V vertices and E edges
+Graph *CreateGraph(int V, int E)
+{
+    Graph *graph = (Graph *)(malloc(sizeof(Graph)));
+    graph->V = V;
+    graph->E = E;
+    graph->edge = (Edge *)(malloc(E * sizeof(Edge)));
+    return graph;
+}
+
+// Print all graph component to the CLI
+void PrintGraph(Graph *graph)
+{
+    printf("Vertices : %d\n", graph->V);
+    printf("Edges : %d\n", graph->E);
+    for (int i = 0; i < graph->E; i++)
+    {
+        printf("%d -- %d = %d\n", graph->edge[i].src, graph->edge[i].dest, graph->edge[i].weight);
+    }
+}
+
+// A function to implement bubble sort
+void bubbleSort(Edge arr[], int n, int type)
+{
+    //Jika type ==1, maka diurutkan berdasarkan weight
+    //Jika type ==2, maka diurutkan berdasarkan src
+    int i, j;
+// #pragma omp parallel num_threads(thread_count) default(none) private(i, j) shared(type, arr, n)
+    for (i = 0; i < n - 1; i++)
+
+        for (j = 0; j < n - i - 1; j++) 
+            if (type == 1)
+            {
+                if (arr[j].weight > arr[j + 1].weight)
+                {
+// #pragma omp critical
+                    {
+                        Edge temp = arr[j];
+                        arr[j] = arr[j + 1];
+                        arr[j + 1] = temp;
+                    }
+                }
+            }
+            else
+            {
+                if (arr[j].src > arr[j + 1].src)
+// #pragma omp critical
+                {
+                    Edge temp = arr[j];
+                    arr[j] = arr[j + 1];
+                    arr[j + 1] = temp;
+                }
+                else if (arr[j].src == arr[j + 1].src && arr[j].dest > arr[j + 1].dest)
+// #pragma omp critical
+                {
+                    Edge temp = arr[j];
+                    arr[j] = arr[j + 1];
+                    arr[j + 1] = temp;
+                }
+            }
+}
+
+/// Create graph based from the adjacency matrix in file
+Graph *ReadArguments()
+{
+    Graph *graph = (Graph *)(malloc(sizeof(Graph)));
+
+    int V, weight;
+    scanf("%d", &V);
+    graph->V = V;
+    graph->edge = (Edge *)(malloc(((V * V - V) / 2) * sizeof(Edge)));
+
+    // Read the adjacency matrix
+    int E = 0;
+    for (int i = 0; i < V; i++)
+    {
+        for (int j = 0; j < V; j++)
+        {
+            scanf("%d", &weight);
+            // printf("%d ", weight);
+            if ((weight != -1) && (i <= j))
+            {
+                graph->edge[E].src = i;
+                graph->edge[E].dest = j;
+                graph->edge[E].weight = weight;
+                E += 1;
+            }
+        }
+        // printf("\n");
+    }
+    graph->E = E;
+    return graph;
+}
+
+// Structure to represent a subset for union-find
+typedef struct
+{
+    int parent;
+    int rank;
+} Subset;
+
+// Create new subset
+Subset *CreateSubset(int V)
+{
+    Subset *subsets = (Subset *)(malloc(V * sizeof(Subset)));
+
+// Create V subsets with single elements
+// #pragma omp parallel for num_threads(thread_count)
+    for (int i = 0; i < V; i++)
+    {
+        subsets[i].parent = i;
+        subsets[i].rank = 0;
+    }
+    return subsets;
+}
+
+int find(Subset subsets[], int i)
+{
+    // find root and make root as parent of i
+    // (path compression)
+    if (subsets[i].parent != i)
+        subsets[i].parent = find(subsets, subsets[i].parent);
+    return subsets[i].parent;
+}
+
+void Union(Subset subsets[], int x, int y)
+{
+    int xroot = find(subsets, x);
+    int yroot = find(subsets, y);
+
+    // Attach smaller rank tree under root of high
+    // rank tree (Union by Rank)
+    if (subsets[xroot].rank < subsets[yroot].rank)
+        subsets[xroot].parent = yroot;
+    else if (subsets[xroot].rank > subsets[yroot].rank)
+        subsets[yroot].parent = xroot;
+
+    // If ranks are same, then make one as root and
+    // increment its rank by one
+    else
+    {
+        subsets[yroot].parent = xroot;
+        subsets[xroot].rank++;
+    }
+}
+
+// Compare two edges according to their weights.
+int compare(const void *a, const void *b)
+{
+    Edge *a1 = (Edge *)a;
+    Edge *b1 = (Edge *)b;
+    return a1->weight > b1->weight;
+}
+
+int compare_src(const void *a, const void *b)
+{
+    Edge *a1 = (Edge *)a;
+    Edge *b1 = (Edge *)b;
+    return a1->src > b1->src;
+}
+
+// Minimum Spanning Tree using Kruskal's Algorithm
+void KruskalMST(Graph *graph, Edge result[], int *e)
+{
+    int V = graph->V;
+    int i = 0;
+
+    // Step 1: Sort all the edges into correspondent sorted edges
+    // qsort(graph->edge, graph->E, sizeof(graph->edge[0]), compare);
+
+    bubbleSort(graph->edge, graph->E, 1);
+    // Step 2: Allocate memory for creating V subsets
+    Subset *subsets = CreateSubset(V);
+
+    while (((*e) < V - 1) && (i < graph->E))
+    {
+        // Pick the smallest edge of the graph
+        Edge next_edge = graph->edge[i++];
+
+        int x = find(subsets, next_edge.src);
+        int y = find(subsets, next_edge.dest);
+        if (x != y)
+        {
+            result[(*e)++] = next_edge;
+            Union(subsets, x, y);
+        }
+    }
+
+    bubbleSort(result, (*e), 2);
+    return;
+    // qsort(result, e, sizeof(result[0]), compare_src);
+}
+
+void printResult(Edge *result, int e)
+{
+    // printf("%d\n", e);
+    int minimumCost = 0;
+// #pragma omp parallel for
+    for (int i = 0; i < e; i++)
+    {
+// #pragma omp critical
+        minimumCost += result[i].weight;
+    }
+    printf("%d\n", minimumCost);
+    for (int i = 0; i < e; i++)
+    {
+        printf("%d-%d\n", result[i].src, result[i].dest);
+    }
+}
+
+// Driver program to test above functions
+int main(int argc, char** argv)
+{
+    MPI_Init(NULL, NULL);
+    // Get the number of processes
+    int world_size;
+    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
+
+    // Get the rank of the process
+    int world_rank;
+    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
+
+
+    Graph *graph = ReadArguments();
+    Edge result[graph->V];
+    int e = 0;
+    int t = clock();
+    KruskalMST(graph, result, &e);
+    t = clock() - t;
+    printResult(result, e);
+    printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000);
+    MPI_Finalize();
+}
\ No newline at end of file
diff --git a/src/MST_Serial b/src/MST_Serial
deleted file mode 100755
index 3927436b13eb5c70e4182cc7a394f42e3bebbc5a..0000000000000000000000000000000000000000
Binary files a/src/MST_Serial and /dev/null differ
diff --git a/src/hello b/src/hello
new file mode 100755
index 0000000000000000000000000000000000000000..1de23036653bc3c34fc555ce1c6d1e0e66f45edb
Binary files /dev/null and b/src/hello differ