text: import math
  
  
  class Node:
      def __init__(self, key, left, right):
          self.key = key
          self.left = left
          self.right = right
  
  
  class BinarySearchTree:
      def __init__(self, root_key):
          self.root = Node(root_key, None, None)
  
      def insert(self, value):
          cur_node = self.root
          while True:
              if value >= cur_node.key:
                  if cur_node.right is None:
                      cur_node.right = Node(value, None, None)
                      break
                  else:
                      cur_node = cur_node.right
              else:
                  if cur_node.left is None:
                      cur_node.left = Node(value, None, None)
                      break
                  else:
                      cur_node = cur_node.left
  
      def dfs(self):
          def traverse(c=self.root, v=[]):
              v.append(c.key)
              if c.left is not None:
                  traverse(c.left, v)
              if c.right is not None:
                  traverse(c.right, v)
              return v
  
          return traverse()
  
      def bfs(self):
          def traverse(c=self.root, v=[]):
              if c.left is not None:
                  v.append(c.left.key)
              if c.right is not None:
                  v.append(c.right.key)
              if c.left is not None:
                  traverse(c.left, v)
              if c.right is not None:
                  traverse(c.right, v)
              return v
  
          return [self.root.key] + traverse()
  
      def get_node_count(self):
          return print(len(self.bfs()))
  
      def print_values(self):
          return sorted(self.bfs())
  
      def delete_tree(self):
          self.root.left = None
          self.root.right = None
  
      def is_in_tree(self, value):
          if value in self.bfs():
              return True
          return False
  
      def get_height(self):
          x = len(self.bfs())
          return math.log((x - 1) / 2 + 1, 2).__floor__()
  
      def get_min(self):
          return self.print_values()[0]
  
      def get_max(self):
          return self.print_values()[-1]
  
      def delete_value(self, value):
          def traverse(c=self.root, v=[]):
              if c is not None and c.left is not None and c.left.key == value:
                  v.append(c)
                  v.append(c.left)
              if c is not None and c.right is not None and c.right.key == value:
                  v.append(c)
                  v.append(c.right)
              if c is not None and value > c.key:
                  traverse(c.right)
              elif c is not None:
                  traverse(c.left)
              return v
  
          nodes = traverse()
          if nodes[1].left and nodes[1].right is None:
              del nodes[1]
          elif nodes[1].right is None and nodes[1].left is not None:
              if nodes[0].right == nodes[1]:
                  nodes[0].right = nodes[1].left
                  del nodes[1]
              else:
                  nodes[0].left = nodes[1].left
                  del nodes[1]
          elif nodes[1].right is not None and nodes[1].left is None:
              if nodes[0].right == nodes[1]:
                  nodes[0].right = nodes[1].right
                  del nodes[1]
              else:
                  nodes[0].left = nodes[1].right
                  del nodes[1]
          else:
              subtree_start = nodes[1].right
  
              def traverse_subtree(c=subtree_start, cur_lowest=subtree_start):
                  if c.key < cur_lowest.key:
                      cur_lowest = c
                  if c.left is not None:
                      traverse(c.left, cur_lowest)
                  return cur_lowest
  
              smallest_value = traverse_subtree()
              nodes[1].key = smallest_value.key
              del smallest_value
  
      def get_successor(self, value):
          def traverse(c=self.root, v=[]):
              if c.key == value:
                  v.append(c.right.key)
                  return v
              if value > c.key:
                  traverse(c.right, v)
              else:
                  traverse(c.left, v)
              return v
  
          return print(traverse())
  
  
  t1 = BinarySearchTree(10)
  t1.insert(5)
  t1.insert(15)
  t1.insert(2)
  t1.insert(7)
  t1.insert(17)
  t1.insert(13)
  print(t1.bfs())
  t1.delete_value(5)
  print(t1.bfs())
  