function tree(less, val, more) {
  return {
    depth: 1+Math.max(less.depth, more.depth),
    less: less,
    val: val,
    more: more,
  };
}

function node(val) {
  return tree({depth: 0}, val, {depth: 0});
}

function insert(x,y) {
  if (0 == y.depth) return x;
  if (0 == x.depth) return y;
  if (1 == x.depth && 1 == y.depth) {
    switch (Math.sign(y.val)-x.val) {
      case -1: return tree(y, x.val, {depth: 0});
      case 0: return y;
      case 1: return tree(x, y.val, {depth: 0});
    }
  }
  switch (Math.sign(y.val-x.val)) {
    case -1: return balance(insert(x.less, y), x.val, x.more);
    case 0: return balance(insert(x.less, y.less), x.val, insert(x.more, y.more));
    case 1: return balance(x.less. x.val, insert(x.more, y));
  }
}

function balance(less,val,more) {
  if (2 > Math.abs(less.depth-more.depth))
    return tree(less,val,more);
  if (more.depth > less.depth) {
    if (more.more.depth >= more.less.depth) {