program Main;

type
  Node = record
    data : integer;
    left : ^Node;
    right : ^Node
  end;
  pNode = ^Node;

function push(root : pNode; data : integer) : pNode;
var
  r : pNode;
begin
  if root = nil then begin
    new(r);
    r^.data := data;
    r^.left := nil;
    r^.right := nil;
    push := r;
  end else if data < root^.data then begin
    root^.left := push(root^.left, data);
    push := root
  end else begin
    root^.right := push(root^.right, data);
    push := root
  end
end;

function pop(root : pNode; var data : integer) : pNode;
var
  r : pNode;
begin
  if root = nil then begin { never }
    pop := nil
  end  else if root^.left <> nil then begin
    root^.left := pop(root^.left, data);
    pop := root
  end else begin
    r := root^.right;
    data := root^.data;
    dispose(root);
    pop := r
  end
end;

type 
  BinTree = class
  private
    root : pNode;
    flag : boolean;
  public
    constructor Create();
    procedure pushNode(data : integer);
    function popNode(var data : integer) : boolean;
  end;

constructor BinTree.Create();
begin
  root := nil;
  flag := false;
end;

procedure BinTree.pushNode(data : integer);
begin
  root := push(root, data);
  flag := true
end;

function BinTree.popNode(var data : integer) : boolean;
begin
  root := pop(root, data);
  if (root = nil) then
    if (flag = true) then begin
      flag := false;
      popNode := true
     end else
       popNode := false
  else
    popNode := true
end;

const
  N = 10;
  MAX = 1000;
var
  root : BinTree;
  data, i : integer;
begin
  root := BinTree.Create;
  randomize;
  i := 0;
  while (i < 10) do begin
    data := random(MAX);
    root.pushNode(data);
    i := i + 1
  end;
  while (root.popNode(data) = true) do
    writeln(data);
  root.Free
end.
{ end }
