assert (k > 0);
while (--k > 0)
  {
    struct avl_node *y = pa[k];

    if (da[k] == 0)
      {
        y->avl_balance++;
        if (y->avl_balance == +1)
          break;
        else if (y->avl_balance == +2)
          {
            struct avl_node *x = y->avl_link[1];
            if (x->avl_balance == -1)
              {
                struct avl_node *w;
                assert (x->avl_balance == -1);
                w = x->avl_link[0];
                x->avl_link[0] = w->avl_link[1];
                w->avl_link[1] = x;
                y->avl_link[1] = w->avl_link[0];
                w->avl_link[0] = y;
                if (w->avl_balance == +1)
                  x->avl_balance = 0, y->avl_balance = -1;
                else if (w->avl_balance == 0)
                  x->avl_balance = y->avl_balance = 0;
                else /* |w->avl_balance == -1| */
                  x->avl_balance = +1, y->avl_balance = 0;
                w->avl_balance = 0;
                pa[k - 1]->avl_link[da[k - 1]] = w;
              }
            else
              {
                y->avl_link[1] = x->avl_link[0];
                x->avl_link[0] = y;
                pa[k - 1]->avl_link[da[k - 1]] = x;
                if (x->avl_balance == 0)
                  {
                    x->avl_balance = -1;
                    y->avl_balance = +1;
                    break;
                  }
                else
                  x->avl_balance = y->avl_balance = 0;
              }
          }
      }
    else
      {
        y->avl_balance--;
        if (y->avl_balance == -1)
          break;
        else if (y->avl_balance == -2)
          {
            struct avl_node *x = y->avl_link[0];
            if (x->avl_balance == +1)
              {
                struct avl_node *w;
                assert (x->avl_balance == +1);
                w = x->avl_link[1];
                x->avl_link[1] = w->avl_link[0];
                w->avl_link[0] = x;
                y->avl_link[0] = w->avl_link[1];
                w->avl_link[1] = y;
                if (w->avl_balance == -1)
                  x->avl_balance = 0, y->avl_balance = +1;
                else if (w->avl_balance == 0)
                  x->avl_balance = y->avl_balance = 0;
                else /* |w->avl_balance == +1| */
                  x->avl_balance = -1, y->avl_balance = 0;
                w->avl_balance = 0;
                pa[k - 1]->avl_link[da[k - 1]] = w;
              }
            else
              {
                y->avl_link[0] = x->avl_link[1];
                x->avl_link[1] = y;
                pa[k - 1]->avl_link[da[k - 1]] = x;
                if (x->avl_balance == 0)
                  {
                    x->avl_balance = +1;
                    y->avl_balance = -1;
                    break;
                  }
                else
                  x->avl_balance = y->avl_balance = 0;
              }
          }
      }
  }

