input: Write a python function to insert and remove elements in a B-Tree.
  assert '이씨' in bt
  bt.remove('이씨')
  assert '이씨' not in bt
  bt.insert('이씨')
  assert '이씨' in bt
output: class BTreeNode:
      def __init__(self, leaf=False):
          self.leaf = leaf
          self.keys = []
          self.children = []
  
  class BTree:
      def __init__(self, t):
          self.root = BTreeNode(True)
          self.t = t
      
      def insert(self, k):
          root = self.root
          if len(root.keys) == 2 * self.t - 1:
              temp = BTreeNode()
              self.root = temp
              temp.children.insert(0, root)
              self._split_child(temp, 0)
              self._insert_non_full(temp, k)
          else:
              self._insert_non_full(root, k)
      
      def _insert_non_full(self, x, k):
          i = len(x.keys) - 1
          if x.leaf:
              x.keys.append((None, None))
              while i >= 0 and k < x.keys[i]:
                  x.keys[i + 1] = x.keys[i]
                  i -= 1
              x.keys[i + 1] = k
          else:
              while i >= 0 and k < x.keys[i]:
                  i -= 1
              i += 1
              if len(x.children[i].keys) == 2 * self.t - 1:
                  self._split_child(x, i)
                  if k > x.keys[i]:
                      i += 1
              self._insert_non_full(x.children[i], k)
      
      def _split_child(self, x, i):
          t = self.t
          y = x.children[i]
          z = BTreeNode(y.leaf)
          x.children.insert(i + 1, z)
          x.keys.insert(i, y.keys[t - 1])
          z.keys = y.keys[t: (2 * t - 1)]
          y.keys = y.keys[0: (t - 1)]
          if not y.leaf:
              z.children = y.children[t: (2 * t)]
              y.children = y.children[0: (t - 1)]
      
      def remove(self, k):
          self._remove(self.root, k)
          if len(self.root.keys) == 0:
              if len(self.root.children) > 0:
                  self.root = self.root.children[0]
              else:
                  self.root = BTreeNode(True)
      
      def _remove(self, x, k):
          t = self.t
          if x.leaf:
              if k in x.keys:
                  x.keys.remove(k)
                  return
          else:
              for i, key in enumerate(x.keys):
                  if k < key:
                      if len(x.children[i].keys) >= t:
                          self._remove(x.children[i], k)
                      elif len(x.children[i + 1].keys) >= t:
                          self._remove(x.children[i + 1], k)
                      else:
                          self._merge(x, i)
                          self._remove(x.children[i], k)
                      return
                  elif k == key:
                      if x.leaf:
                          x.keys.remove(k)
                      else:
                          if len(x.children[i].keys) >= t:
                              pred = self._get_predecessor(x, i)
                              x.keys[i] = pred
                              self._remove(x.children[i], pred)
                          elif len(x.children[i + 1].keys) >= t:
                              succ = self._get_successor(x, i)
                              x.keys[i] = succ
                              self._remove(x.children[i + 1], succ)
                          else:
                              self._merge(x, i)
                              self._remove(x.children[i], k)
                      return
              last = len(x.keys)
              if k > x.keys[last - 1]:
                  if len(x.children[last].keys) >= t:
                      self._remove(x.children[last], k)
                  elif len(x.children[last - 1].keys) >= t:
                      self._remove(x.children[last - 1], k)
                  else:
                      self._merge(x, last - 1)
                      self._remove(x.children[last - 1], k)
      
      def _get_predecessor(self, x, i):
          current = x.children[i]
          while not current.leaf:
              current = current.children[-1]
          return current.keys[-1]
      
      def _get_successor(self, x, i):
          current = x.children[i + 1]
          while not current.leaf:
              current = current.children[0]
          return current.keys[0]
      
      def _merge(self, x, i):
          c1 = x.children[i]
          c2 = x.children[i + 1]
          c1.keys.append(x.keys[i])
          c1.keys.extend(c2.keys)
          if not c1.leaf:
              c1.children.extend(c2.children)
          x.keys.pop(i)
          x.children.pop(i