#define N       32
 
class Node
{
    Node *left, *right;
    I64   n;
};
 
I64   n1, n2, common_ancestor;
Node *root;
 
#define X_SPACING       16
#define Y_SPACING       45
#define ARROW_SPACING   3
 
U0 ShowTree(CDC *dc, Node *tmpn, I64 *_node_x, I64 *_tree_x, I64 y)
{
    I64 node_x;

    if (tmpn)
    {
        if (tmpn->left)
        {
            ShowTree(dc, tmpn->left, &node_x, _tree_x, y + Y_SPACING);
            dc->color = BLUE;
            GrArrow3(dc, *_tree_x, y, 0, node_x + ARROW_SPACING, y + Y_SPACING - ARROW_SPACING, 0);
        }
        if (tmpn->n == n1 || tmpn->n == n2)
        {
            if (tmpn->n == common_ancestor)
                dc->color = YELLOW;
            else
                dc->color = RED;
        }
        else if (tmpn->n == common_ancestor)
            dc->color = GREEN;
        else
            dc->color = BLUE;

        *_node_x = *_tree_x;
        GrPrint(dc, *_node_x, y, "%d", tmpn->n);
        *_tree_x += X_SPACING;

        if (tmpn->right)
        {
            ShowTree(dc, tmpn->right, &node_x, _tree_x, y + Y_SPACING);
            dc->color = BLUE;
            GrArrow3(dc, *_node_x, y, 0, node_x - ARROW_SPACING, y + Y_SPACING - ARROW_SPACING, 0);
        }
    }
}
 
U0 DrawIt(CTask *, CDC *dc)
{
    I64 node_x = 0, tree_x = 0;

    ShowTree(dc, root, &node_x, &tree_x, 20);
}

U0 TreeAdd(Node **_root, Node *tmpn)
{
    Node *root = *_root;

    if (!root)
        *_root = tmpn;
    else if (tmpn->n == root->n)
        Free(tmpn);
    else if (tmpn->n < root->n)
        TreeAdd(&root->left, tmpn);
    else
        TreeAdd(&root->right, tmpn);
}

U0 TreeNew()
{
    I64   i;
    Node *tmpn;

    for (i = 0; i < N; i++)
    {
        tmpn = CAlloc(sizeof(Node));
        tmpn->n = RandU16 % N;

        if (i == N - 1)
            n1 = tmpn->n;
        else if (i == N - 2)
            n2 = tmpn->n;

        TreeAdd(&root, tmpn);
        Sleep(50);
    }
}
 
U0 TreeCommonAncestorFind(Node *root)
{
    if (root && root->n != n1 && root->n != n2)
    {
        common_ancestor = root->n;
        if (n1 < root->n && n2 < root->n)
            TreeCommonAncestorFind(root->left);
        else if (n1 > root->n && n2 > root->n)
            TreeCommonAncestorFind(root->right);
    }
}
 
U0 TreeCommonAncestor()
{//Make tree and find common ancestor to n1 & n2.
    root = NULL;
    n1 = n2 = common_ancestor = 0;

    SettingsPush; //See SettingsPush
    Fs->draw_it = &DrawIt;
    DocClear;
    "Scroll with {CTRL-Left Grab}.\n";
    try
    {
        TreeNew;
        TreeCommonAncestorFind(root);
        PressAKey;
    }
    catch
        PutExcept;
    SettingsPop;
}

TreeCommonAncestor;
/*
Be careful with recursive routines in ZealOS
because the stack does not grow and will overflow.

See ::/Demo/StackGrow.ZC.
*/