diff --git a/src/bptree.c b/src/bptree.c
index b55102442933cb3b9f4bd017bf19e6734fda4d6b..330dc1147eaae5da29790b40e2041499d19d7dd9 100644
--- a/src/bptree.c
+++ b/src/bptree.c
@@ -1,29 +1,29 @@
 #include "bptree.h"
 
 #include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-///
+#include "sorted_array.h"
 
-static bool has_minimum_keys(BPTreeNode *root);
-static bool has_maximum_keys(BPTreeNode *root);
+// static bool has_minimum_keys(BPTreeNode *node);
+static bool has_maximum_keys(BPTreeNode *node);
 
-static bool has_minimum_keys(BPTreeNode *root) {
-    return root->keys_length == root->order;
-}
+// static bool has_minimum_keys(BPTreeNode *node) {
+//     return node->keys_length == node->order;
+// }
 
-static bool has_maximum_keys(BPTreeNode *root) {
-    return root->keys_length == 2 * root->order;
+static bool has_maximum_keys(BPTreeNode *node) {
+    return node->keys_length == 2 * node->order;
 }
 
-///
-
 BPTreeNode *bptree_init(int order) {
     BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode));
     root->order = order;
     root->is_leaf = true;
     root->keys_length = 0;
-    root->keys = (int *)malloc(sizeof(int) * (2 * order));
+    root->keys = (uint64_t *)malloc(sizeof(uint64_t) * (2 * order));
     root->children_length = 0;
     root->children = (BPTreeNode **)malloc(sizeof(BPTreeNode *) * (2 * order + 1));
     return root;
@@ -31,7 +31,7 @@ BPTreeNode *bptree_init(int order) {
 
 void bptree_destroy(BPTreeNode **root) {
     for (int i = 0; i < (*root)->children_length; i++) {
-        bptree_destroy((*root)->children[i]);
+        bptree_destroy(&(*root)->children[i]);
     }
 
     free((*root)->keys);
@@ -40,6 +40,131 @@ void bptree_destroy(BPTreeNode **root) {
     *root = NULL;
 }
 
+// ...
+
 // Insertion
 
+static void redistribute_keys(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) {
+    for (int i = right_index; i < left_node->keys_length; i++) {
+        array_append(&right_node->keys_length, right_node->keys, left_node->keys[i]);
+    }
+
+    left_node->keys_length = left_index;
+}
+
+uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_node) {
+    int virtual_insertion_index = lower_bound(node->keys_length, node->keys, key);
+    int median_index = node->keys_length / 2;
+    uint64_t median_value;
+    *right_node = bptree_init(node->order);
+
+    if (virtual_insertion_index < median_index) {
+        median_value = node->keys[median_index - 1];
+        redistribute_keys(node, *right_node, median_index - 1, median_index - 1);
+        sorted_array_insert(&node->keys_length, node->keys, key);
+    } else if (virtual_insertion_index > median_index) {
+        median_value = node->keys[median_index];
+        redistribute_keys(node, *right_node, median_index, median_index);
+        sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key);
+    } else {
+        median_value = key;
+        redistribute_keys(node, *right_node, median_index, median_index);
+        sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key);
+    }
+
+    // TODO : Linked List
+
+    return median_value;
+}
+
+// static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) {
+//     for (int i = right_index; i < left_node->children_length; i++) {
+//         array_append_BPTreeNode(&right_node->children_length, right_node->children, left_node->children[i]);
+//     }
+
+//     left_node->children_length = left_index;
+// }
+
+static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node) {
+    BPTreeNode *left_node = bptree_init(root->order);
+    left_node->is_leaf = split_right_node->is_leaf;
+
+    for (int i = 0; i < root->keys_length; i++) {
+        array_append(&left_node->keys_length, left_node->keys, root->keys[i]);
+    }
+
+    for (int i = 0; i < root->children_length; i++) {
+        array_append_BPTreeNode(&left_node->children_length, left_node->children, root->children[i]);
+    }
+
+    root->is_leaf = false;
+    root->keys_length = 0;
+    root->children_length = 0;
+
+    array_append(&root->keys_length, root->keys, median_value);
+    array_append_BPTreeNode(&root->children_length, root->children, left_node);
+    array_append_BPTreeNode(&root->children_length, root->children, split_right_node);
+}
+
+static void insert_full(BPTreeNode *root, int *parents_length, BPTreeNode **parents, BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node) {
+    uint64_t median_value;
+    BPTreeNode *split_right_node;
+
+    if (node->is_leaf) {
+        median_value = split_leaf(node, key, &split_right_node);
+    } else {
+        // TODO
+        printf("TODO\n");
+    }
+
+    if (node == root) {
+        grow(root, median_value, split_right_node);
+    } else {
+        // TODO
+        printf("TODO\n");
+    }
+}
+
+static void insert_non_full(BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node) {
+    int insertion_index = sorted_array_insert(&node->keys_length, node->keys, key);
+
+    if (previous_split_right_node != NULL) {
+        array_insert_at_index_BPTreeNode(&node->children_length, node->children, insertion_index + 1, previous_split_right_node);
+    }
+}
+
+static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, int *parents_length, BPTreeNode ***parents) {
+    BPTreeNode *current = root;
+    *parents_length = 0;
+    // TODO : 10 is not enough.
+    *parents = (BPTreeNode **)malloc(sizeof(BPTreeNode *) * 10);
+
+    while (!current->is_leaf) {
+        array_append_BPTreeNode(parents_length, *parents, current);
+        int child_index = lower_bound(current->keys_length, current->keys, key);
+
+        if (child_index < current->keys_length && current->keys[child_index] == key) {
+            child_index += 1;
+        }
+
+        current = current->children[child_index];
+    }
+
+    return current;
+}
+
+void bptree_insert(BPTreeNode *root, uint64_t key) {
+    int parents_length;
+    BPTreeNode **parents;
+    BPTreeNode *leaf = find_leaf(root, key, &parents_length, &parents);
+
+    if (has_maximum_keys(leaf)) {
+        insert_full(root, &parents_length, parents, leaf, key, NULL);
+    } else {
+        insert_non_full(leaf, key, NULL);
+    }
+
+    free(parents);
+}
+
 // Deletion
diff --git a/src/bptree.h b/src/bptree.h
index 559ccfeac5e18d51e9e48f602afaa93e90bdfc5b..d5bc03a34c4e075847f56ece5be8a420dcc05a52 100644
--- a/src/bptree.h
+++ b/src/bptree.h
@@ -1,13 +1,14 @@
 #ifndef BPTREE_H
 #define BPTREE_h
 
-#include "stdbool.h"
+#include <stdbool.h>
+#include <stdint.h>
 
 typedef struct BPTreeNode {
     int order;
     bool is_leaf;
     int keys_length;
-    int *keys;
+    uint64_t *keys;
     int children_length;
     struct BPTreeNode **children;
 } BPTreeNode;
@@ -15,4 +16,12 @@ typedef struct BPTreeNode {
 BPTreeNode *bptree_init(int order);
 void bptree_destroy(BPTreeNode **root);
 
+// ...
+
+// Insertion
+
+void bptree_insert(BPTreeNode *root, uint64_t key);
+
+// Deletion
+
 #endif
diff --git a/src/bptree.o b/src/bptree.o
new file mode 100644
index 0000000000000000000000000000000000000000..1c3356f81150672ea30605e2d69c077b43918883
Binary files /dev/null and b/src/bptree.o differ
diff --git a/src/main.c b/src/main.c
index 3da830eaa6c695c46fe8f7194759adcb75c41e20..656890d2ee849a1f0eec45b9b955377a69807054 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,28 +2,19 @@
 #include <stdlib.h>
 
 #include "sorted_array.h"
+#include "bptree.h"
 
 int main() {
-    int *array = (int *)malloc(sizeof(int) * 10);
-    int array_length = 0;
-
-    sorted_array_insert(array, &array_length, 3);
-    sorted_array_insert(array, &array_length, 11);
-    sorted_array_insert(array, &array_length, 5);
-    sorted_array_insert(array, &array_length, 1);
-    sorted_array_insert(array, &array_length, 15);
-    sorted_array_insert(array, &array_length, 12);
-    sorted_array_insert(array, &array_length, 8);
-    sorted_array_print(array, array_length);
-
-    sorted_array_delete(array, &array_length, 12);
-    sorted_array_delete(array, &array_length, 1);
-    sorted_array_delete(array, &array_length, 15);
-    sorted_array_delete(array, &array_length, 5);
-    sorted_array_delete(array, &array_length, 8);
-    sorted_array_delete(array, &array_length, 11);
-    sorted_array_delete(array, &array_length, 3);
-    sorted_array_print(array, array_length);
+    BPTreeNode *root = bptree_init(2);
+    // [8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55
+    bptree_insert(root, 8);
+    bptree_insert(root, 12);
+    bptree_insert(root, 11);
+    bptree_insert(root, 47);
+    bptree_insert(root, 22);
+    array_print(root->keys_length, root->keys);
+    array_print(root->children[0]->keys_length, root->children[0]->keys);
+    array_print(root->children[1]->keys_length, root->children[1]->keys);
 
     return EXIT_SUCCESS;
 }
diff --git a/src/main.o b/src/main.o
index 430793ffa0d07259fdf13973a75857418dc744d3..7cead98a5619bbb3096b135d6cd99d66c5f6d86c 100644
Binary files a/src/main.o and b/src/main.o differ
diff --git a/src/program b/src/program
index d77345c41e98d225093d0a372100bb75b4155945..b11cbd80e7c3c03fd3956742bc7631c4cbbb3342 100644
Binary files a/src/program and b/src/program differ
diff --git a/src/sorted_array.c b/src/sorted_array.c
index 0bbf3a06e28b0a7653ea4fc93c45f5c08f5f6486..50834dcd1a75503e8a406e4c8a139e46e7f9d093 100644
--- a/src/sorted_array.c
+++ b/src/sorted_array.c
@@ -1,10 +1,11 @@
 #include "sorted_array.h"
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 
-int lower_bound(int *array, int array_length, int value) {
+int lower_bound(int array_length, uint64_t *array, uint64_t value) {
     int low = 0;
     int high = array_length - 1;
 
@@ -23,7 +24,7 @@ int lower_bound(int *array, int array_length, int value) {
     return low;
 }
 
-int sorted_array_find_index(int *array, int array_length, int value) {
+int sorted_array_find_index(int array_length, uint64_t *array, uint64_t value) {
     int low = 0;
     int high = array_length - 1;
 
@@ -42,8 +43,8 @@ int sorted_array_find_index(int *array, int array_length, int value) {
     return -1;
 }
 
-bool sorted_array_search(int *array, int array_length, int value, int *index) {
-    int i = sorted_array_find_index(array, array_length, value);
+bool sorted_array_search(int array_length, uint64_t *array, uint64_t value, int *index) {
+    int i = sorted_array_find_index(array_length, array, value);
 
     if (index != NULL) {
         *index = i;
@@ -52,16 +53,8 @@ bool sorted_array_search(int *array, int array_length, int value, int *index) {
     return i != -1;
 }
 
-void sorted_array_print(int *array, int array_length) {
-    for (int i = 0; i < array_length; i++) {
-        printf("%d ", array[i]);
-    }
-
-    printf("\n");
-}
-
-int sorted_array_insert(int *array, int *array_length, int value) {
-    int insertion_index = lower_bound(array, *array_length, value);
+int sorted_array_insert(int *array_length, uint64_t *array, uint64_t value) {
+    int insertion_index = lower_bound(*array_length, array, value);
 
     for (int i = *array_length - 1; i >= insertion_index; i--) {
         array[i + 1] = array[i];
@@ -72,8 +65,8 @@ int sorted_array_insert(int *array, int *array_length, int value) {
     return insertion_index;
 }
 
-void sorted_array_delete(int *array, int *array_length, int value) {
-    int index = sorted_array_find_index(array, *array_length, value);
+void sorted_array_delete(int *array_length, uint64_t *array, uint64_t value) {
+    int index = sorted_array_find_index(*array_length, array, value);
 
     for (int i = index; i < *array_length; i++) {
         array[i] = array[i + 1];
@@ -81,3 +74,30 @@ void sorted_array_delete(int *array, int *array_length, int value) {
 
     *array_length -= 1;
 }
+
+void array_append(int *array_length, uint64_t *array, uint64_t value) {
+    array[*array_length] = value;
+    *array_length += 1;
+}
+
+void array_print(int array_length, uint64_t *array) {
+    for (int i = 0; i < array_length; i++) {
+        printf("%ld ", array[i]);
+    }
+
+    printf("\n");
+}
+
+void array_insert_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int insertion_index, BPTreeNode *value) {
+    for (int i = *array_length - 1; i >= insertion_index; i--) {
+        array[i + 1] = array[i];
+    }
+
+    array[insertion_index] = value;
+    *array_length += 1;
+}
+
+void array_append_BPTreeNode(int *array_length, BPTreeNode **array, BPTreeNode *value) {
+    array[*array_length] = value;
+    *array_length += 1;
+}
diff --git a/src/sorted_array.h b/src/sorted_array.h
index e1088323b25e7064aaa6617138c602bb3da527e8..5192d0fa57e1f7c04232b7f99539066cce16985d 100644
--- a/src/sorted_array.h
+++ b/src/sorted_array.h
@@ -2,14 +2,23 @@
 #define SORTED_ARRAY_H
 
 #include <stdbool.h>
+#include <stdint.h>
 
-int lower_bound(int *array, int array_length, int value);
+int lower_bound(int array_length, uint64_t *array, uint64_t value);
 
-int sorted_array_find_index(int *array, int array_length, int value);
-bool sorted_array_search(int *array, int array_length, int value, int *index);
-void sorted_array_print(int *array, int array_length);
+int sorted_array_find_index(int array_length, uint64_t *array, uint64_t value);
+bool sorted_array_search(int array_length, uint64_t *array, uint64_t value, int *index);
 
-int sorted_array_insert(int *array, int *array_length, int value);
-void sorted_array_delete(int *array, int *array_length, int value);
+int sorted_array_insert(int *array_length, uint64_t *array, uint64_t value);
+void sorted_array_delete(int *array_length, uint64_t *array, uint64_t value);
+
+void array_print(int array_length, uint64_t *array);
+void array_append(int *array_length, uint64_t *array, uint64_t value);
+
+typedef struct BPTreeNode BPTreeNode;
+
+void array_insert_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int insertion_index, BPTreeNode *value);
+void array_append_BPTreeNode(int *array_length, BPTreeNode **array, BPTreeNode *value);
+// void array_delete_at_index_BPTreeNode(BPTreeNode **array, int *array_length, int index);
 
 #endif
diff --git a/src/sorted_array.o b/src/sorted_array.o
index b5cdc315a1c1cef35f42c2424ca12b6288091a13..4d28f285dc92c82c19a672638a679bb237d9a952 100644
Binary files a/src/sorted_array.o and b/src/sorted_array.o differ