interface Sync
{
	void acquire() throws InterruptedException;
	void release();
	boolean attempt(long msec) throws InterruptedException;
}

class Semaphore implements Sync
{
	protected long permits; // current number of permits available
	
	public Semaphore(long initialPermits)
	{
		permits = initialPermits;
	}
	
	public synchronized long permits()
	{
		return permits;
	}
	
	public synchronized void release()
	{
		++permits;
		notify();
	}
	
	public void acquire() throws InterruptedException
	{
		if (Thread.interrupted()) throw new InterruptedException();
		synchronized(this)
		{
			try
			{
				while (permits <= 0)
					wait();
				--permits;
			}
			catch (InterruptedException ie)
			{
				notify();
				throw ie;
			}
		}
	}
	
	public boolean attempt(long msecs) throws InterruptedException
	{
		if (Thread.interrupted()) throw new InterruptedException();
		synchronized(this)
		{
			if (permits > 0)
			{
				--permits;
				return true;
			}
			else if (msecs <= 0)
				return false;
			else
			{
				try
				{
					long startTime = System.currentTimeMillis();
					long waitTime = msecs;
					
					while (true)
					{
						wait(waitTime);
						if (permits > 0)
						{
							--permits;
							return true;
						}
						else
						{
							long now = System.currentTimeMillis();
							waitTime = msecs - (now - startTime);
							if (waitTime <= 0)
								return false;
						}
					}
				}
				catch (InterruptedException ie)
				{
					notify();
					throw ie;
				}
			}
		}
	}
}