import java.math.BigInteger;
import java.util.*;

public class Factorial {

    // creat dynamic cache
    protected static Vector table = new Vector();

    // initialize first element in the cache
    static {
	table.addElement(BigInteger.valueOf(1));
    }


    //
    public static BigInteger factorial(int n) throws IllegalArgumentException {

	if (n < 0) {
	    throw new IllegalArgumentException("argument must be non-negative");
	}

	for (int size = table.size(); size <= n; size++) {
	    BigInteger lastFact = (BigInteger) table.elementAt(size - 1);
	    BigInteger nextFact = lastFact.multiply(BigInteger.valueOf(size));
	    table.addElement(nextFact);
	}

	return (BigInteger) table.elementAt(n);
    }


    // a simple driver to use as a standalone test for factorial() method
    public static void main(String[] args) {
	System.out.println();

	// try to do the job, print generic error message in case of any error
	// such as ArrayIndexOutOfBoundsException
	try {
	    int n = Integer.parseInt(args[0]);
	    System.out.println("--> " + n + "! = " + factorial(n));
	} catch (Exception e) {
	    System.out.println("--> Invalid Input");
	}
    }
}
