docs: function _concat(a, b, mutate) {
  	var aHeight = a.height;
  	var bHeight = b.height;
  
  	if (aHeight === 0 && bHeight === 0) {
  		return [a, b];
  	}
  
  	if (aHeight !== 1 || bHeight !== 1) {
  		if (aHeight === bHeight) {
  			a = (0, _util.nodeCopy)(a, mutate);
  			b = (0, _util.nodeCopy)(b, mutate);
  			let tuple = _concat((0, _util.last)(a), (0, _util.first)(b), mutate);
  			let a0 = tuple[0];
  			let b0 = tuple[1];
  			insertRight(a, a0);
  			insertLeft(b, b0);
  		} else if (aHeight > bHeight) {
  			a = (0, _util.nodeCopy)(a, mutate);
  			let tuple = _concat((0, _util.last)(a), b, mutate);
  			let a0 = tuple[0];
  			let b0 = tuple[1];
  			insertRight(a, a0);
  			b = (0, _util.parentise)(b0, b0.height + 1);
  		} else {
  			b = (0, _util.nodeCopy)(b, mutate);
  			var tuple = _concat(a, (0, _util.first)(b), mutate);
  			var left = tuple[0].length === 0 ? 0 : 1;
  			var right = left === 0 ? 1 : 0;
  			insertLeft(b, tuple[left]);
  			a = (0, _util.parentise)(tuple[right], tuple[right].height + 1);
  		}
  	}
  
  	// Check if balancing is needed and return based on that.
  	if (a.length === 0 || b.length === 0) {
  		return [a, b];
  	}
  
  	var toRemove = calcToRemove(a, b);
  	if (toRemove <= _const.E) {
  		return [a, b];
  	}
  	return shuffle(a, b, toRemove);
  }