// $Id: prodcons.csharp,v 1.0 2002/04/30 17:25:00 dada Exp $
// http://dada.perl.it/shootout/

// based on a sample from the Microsoft .NET SDK Documentation

using System;
using System.Threading;
using System.Collections;

class prodcons {

    private int   m_produced = 0;
    private int   m_consumed = 0;
    private int   m_count = 0;
    private Queue m_smplQueue;
    
    public prodcons(int count) {
        m_count = count;
        m_smplQueue = new Queue(); 
    }

    public void Producer() {
        lock(m_smplQueue) {
            while(m_produced < m_count) {
               //Wait, if the queue is busy.
               Monitor.Wait(m_smplQueue);
               //Push one element.
               m_smplQueue.Enqueue(m_produced);
               //Release the waiting thread.
               Monitor.Pulse(m_smplQueue);   
               m_produced++;
            }
        }
    }

    public void Consumer() {

        while(m_consumed < m_count) {
            lock(m_smplQueue) {
                Monitor.Pulse(m_smplQueue);
                while(Monitor.Wait(m_smplQueue,1000)) {
                    //Pop the first element.
                    m_smplQueue.Dequeue();
                    //Release the waiting thread.
                    Monitor.Pulse(m_smplQueue);
                    m_consumed++;
                }
            }
        }
    }
   
    public void run() {         
         //Create the first thread.
         Thread tProducer = new Thread(new ThreadStart(this.Producer));
         //Create the second thread.
         Thread tConsumer = new Thread(new ThreadStart(this.Consumer));
         //Start threads.
         tProducer.Start();
         tConsumer.Start();
         //wait to the end of the two threads
         tProducer.Join();
         tConsumer.Join();         
         //Print the number of the queue elements.
         Console.WriteLine(this.m_produced.ToString() + " " + this.m_consumed.ToString());     
    }
}

class App {
    public static int Main(String[] args) {
        int n;
        n = System.Convert.ToInt32(args[0]);
        if(n < 1) n = 1;
        new prodcons(n).run();
        return 0;
    }
}