class Table
{
	boolean forkInUse[];
	
	public Table(int seats)
	{
		forkInUse = new boolean[seats];
		for (int i=0; i<forkInUse.length; i++)
			forkInUse[i] = false;
	} //constructor

	private int left(int i)
	{
		return i;
	} //left()

	private int right(int i)
	{
		if (i+1 < forkInUse.length){
			return (i+1);
		} //if
		else {
			return 0;
		} //else
	} //right()
	
	public synchronized void useFork(int seat)
	{
		while( forkInUse[left(seat)]  || forkInUse[right(seat)] )	
		{
			System.out.println("Philosopher #"+Thread.currentThread().getName()+" is waiting for forks");
			try
			{
				wait();
			} //try
			catch (InterruptedException ie)
			{
				System.out.println("An InterruptedException caught\n"+ie.getMessage());
				ie.printStackTrace();
				System.exit(1);
			} //catch()
		} //while
		forkInUse[left(seat)] = true;
		forkInUse[right(seat)] = true;
	} //useFork()
	
	public synchronized void releaseFork(int seat)
	{
		forkInUse[left(seat)] = false;
		forkInUse[right(seat)] = false;
		notifyAll();
	} //relaeaseFork()
} //class Table
	
class Philosopher implements Runnable
{
	Table myTable;
	int seat;
	
	public Philosopher(Table table, int seat)
	{
		myTable = table;
		this.seat = seat;
	} //constructor
	
	public void run()
	{
		while(true)
		{
			think(seat);
			myTable.useFork(seat);
			eat(seat);
			myTable.releaseFork(seat);
		} //loop endlessly
	} //run()
		
	void think(int seat)
	{
		System.out.println("Philosopher #"+Thread.currentThread().getName()+" is thinking");
		try
		{
			Thread.sleep( (int) (Math.random() * 200) );
		} //try
		catch (InterruptedException ie)
		{
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
	} //think()

	void eat(int seat)
	{
		System.out.println("Philosopher #"+Thread.currentThread().getName()+" is eating");
		try
		{
			Thread.sleep( (int) (Math.random() * 200) );
		} //try
		catch (InterruptedException ie)
		{
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
		System.out.println("Philosopher #"+Thread.currentThread().getName()+" finished eating");
	} //eat()
} //class Philosopher

public class HungryPhilosophers
{
	public static void main(String argv[])
	{
		int hungryPhilosophers = Integer.parseInt(argv[0]);
		Table table = new Table( hungryPhilosophers );
		for (int i=0; i<hungryPhilosophers; i++)
		{
			new Thread(new Philosopher(table, i),""+(i+1)).start();
		} //for
	} //main()
} //class HungryPhilosophers