code: function apportion(v, w, ancestor) {
      if (w) {
        var vip = v,
            vop = v,
            vim = w,
            vom = vip.parent.children[0],
            sip = vip.m,
            sop = vop.m,
            sim = vim.m,
            som = vom.m,
            shift;
        while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
          vom = nextLeft(vom);
          vop = nextRight(vop);
          vop.a = v;
          shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
          if (shift > 0) {
            moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
            sip += shift;
            sop += shift;
          }
          sim += vim.m;
          sip += vip.m;
          som += vom.m;
          sop += vop.m;
        }
        if (vim && !nextRight(vop)) {
          vop.t = vim;
          vop.m += sim - sop;
        }
        if (vip && !nextLeft(vom)) {
          vom.t = vip;
          vom.m += sip - som;
          ancestor = v;
        }
      }
      return ancestor;
    }
docs: The core of the algorithm. Here, a new subtree is combined with the previous subtrees. Threads are used to traverse the inside and outside contours of the left and right subtree up to the highest common level. The vertices used for the traversals are vi+, vi-, vo-, and vo+, where the superscript o means outside and i means inside, the subscript - means left subtree and + means right subtree. For summing up the modifiers along the contour, we use respective variables si+, si-, so-, and so+. Whenever two nodes of the inside contours conflict, we compute the left one of the greatest uncommon ancestors using the function ANCESTOR and call MOVE SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. Finally, we add a new thread (if necessary).