class Stack {  // STACK AS A MONITOR
  int maxSize, siz;
  Object[] elems;
  public synchronized void push(Object o) 
             throws InterruptedException {
    while (full()) { wait(); }
    elems[siz - 1] = o;
    notifyAll();
  }
  public synchronized void pop() {
    if (!empty()) { siz -= 1; }
    notifyAll();
  }
  public synchronized Object top()
             throws InterruptedException {
    while (empty()) { wait(); }
    return elems[siz - 1];
  }
  public synchronized boolean full() {
    return siz == maxSize;
  }
  public synchronized boolean empty() {
    return siz == 0;
  }
  Stack(int msiz) {
    maxSize = msiz;
    siz = 0;
    elems = new Object[msiz];
  }
}
