class Stack
{	private int Size;
	private int V[];
	
	public Stack (int capacity)
	{	V=new int[capacity];
		Size=0;
	}

	// lege ein Element auf den Stack
	public void push (int value)
	{	V[Size++]=value; // speichern und Size erhoehen
	}
	
	// ziehe ein Element from Stack
	public int pull ()
	{	Size--; // Size erniedrigen
		return V[Size]; // Element nach dem letzten zurückgeben
	}
	
	// gib Anzahl der Elemente zurueck
	public int size ()
	{	return Size;
	}
	
	// lies oberstes Element
	public int peek ()
	{	return V[Size-1];
	}
}

class Tower extends Stack
{	private int Number;
	public Tower (int capacity, int number)
	{	super(capacity);
		Number=number;
	}
	
	// push mit Test, ob oberstes Element kleiner ist
	public void push (int value)
	{	if (size()==0 || peek()>value) super.push(value);
		else System.out.println("Illegal move");
	}
	
	public int number ()
	{	return Number;
	}
}

public class Hanoi
{	static Tower A,B,C;

	static public void main (String args[])
	{	int n=4;
		// Tuerme beschaffen:
		A=new Tower(n,1); B=new Tower(n,2); C=new Tower(n,3);
		// Turm A auffuellen
		for (int i=n; i>=1; i--) A.push(i);
		// Problem loesen:
		move(n,A,B,C);
	}

	// Rekursive move-Methode
	static void move (int n, Tower a, Tower b, Tower c)
	{	if (n==1)
		{	b.push(a.pull()); // tatsaechliche Simulation der Bewegung
			System.out.println("Move disk from "+a.number()+" to "+b.number());
				// Ausdruck der Bewegung
		}
		else
		{	move(n-1,a,c,b);
			move(1,a,b,c);
			move(n-1,c,b,a);
		}
	}
}
