anchor.diff:      min_max(util:ceil(util:log2(N / P1E)), 1, MaxSize).
   
   %% @doc Calculates from a total P1E the (next) P1E to use for signature and
  -%%      sub-tree reconciliations.
  --spec merkle_next_p1e(BranchFactor::pos_integer(), P1ETotal::float()) -> P1E::float().
  +%%      sub-tree/trivial reconciliations.
  +-spec merkle_next_p1e(BranchFactor::pos_integer(), P1ETotal::float())
  +    -> {P1E_I::float(), P1E_L::float()}.
   merkle_next_p1e(BranchFactor, P1ETotal) ->
  -    % current node can make a mistake or any of its BranchFactor children
  -    % => current node's probability of 0 errors = P0E(child)^(BranchFactor+1)
  +    % mistakes caused by:
  +    % inner node: current node or any of its BranchFactor children (B=BranchFactor+1)
  +    % leaf node: current node or the following trivial reconciliation (B=2)
  +    % => current node's probability of 0 errors = P0E(child)^B
       % however, we cannot use P0E=(1-P1E) since it is near 1 and its floating
       % point representation is sub-optimal!
  -    % => use Taylor expansion of P1E_next = 1 - (1-P1E)^(1/BranchFactor)
  -    BF = BranchFactor + 1,
  -    _P1E = P1ETotal / BF +
  -              (BF - 1) * P1ETotal * P1ETotal / (2 * BF * BF). % +O[p^3]
  +    % => use Taylor expansion of P1E_next = 1 - (1-P1E)^(1/B)
  +    BI = BranchFactor + 1,
  +    P1E_I = P1ETotal / BI +
  +              (BI - 1) * P1ETotal * P1ETotal / (2 * BI * BI), % +O[p^3]
  +    P1E_L = P1ETotal / 2 + P1ETotal * P1ETotal / 8, % +O[p^3]
  +    {P1E_I, P1E_L}.
   
   %% @doc Calculates the new signature sizes based on the next P1E as in
   %%      merkle_next_p1e/2
  
positive.code: %%           util:ceil(
  %%             util:log2(
  %%               % note: see TODO above for P0E precision!
  %%               1 / (1 - math:pow(1 - P1E / (2 * BucketSize), 1 / L))
  %%                      )), 1, 160),
      % approx (Puiseux Series of the above):
      NextSigSizeL =
          min_max(
            util:ceil(
              (math:log(2 * BucketSize * L) - math:log(P1E)) / math:log(2) +
                  (1 - L) * P1E / (BucketSize * L * math:log(16))
                     ), 1, 160),
  
      ?DBG_ASSERT(NextSigSizeL >= NextSigSizeI),
  %%     log:pal("P1E: ~p, \tSigSizeI: ~B, \tSigSizeL: ~B~n"
  %%             "Buckets: ~B, \tMyMI: ~B, \tOtMI: ~B, \tMyML: ~B, \tOtML: ~B",
  %%             [P1E, NextSigSizeI, NextSigSizeL,
  %%              BucketSize, MyMaxItemsCount, OtherMaxItemsCount, MyMaxLeafCount, OtherMaxLeafCount]),
      {P1E, NextSigSizeI, NextSigSizeL}.
  
  -compile({nowarn_unused_function, {min_max_feeder, 3}}).
  -spec min_max_feeder(X::number(), Min::number(), Max::number())
  
negative.code:         min_max(
            util:ceil(
              util:log2(erlang:max(1, MyMaxItemsCount + OtherMaxItemsCount)
                            / P1E_I)), 1, 160),
  
      L = erlang:max(MyMaxLeafCount, OtherMaxLeafCount),
      % exact, but due to problems with precision near 1 not feasible:
  