#include "powMod.h"

/* int pow mod's */
unsigned int uiPowMod(unsigned int a, unsigned int n, unsigned int mod) {
        if (n <= 0)
                return 1;
        return (a * uiPowMod(a, n-1, mod)) % mod;
}

int iPowMod(int a, int n, int mod) {
        if (n <= 0)
                return 1;
        return (a * iPowMod(a, n-1, mod)) % mod;
}

/* long long pow mod's */
unsigned long long ullPowMod(unsigned long long a, unsigned long long n, unsigned long long mod) {
        if (n <= 0)
                return 1;
        return (a * ullPowMod(a, n-1, mod)) % mod;
}

long long llPowMod(long long a, long long n, long long mod) {
        if (n <= 0)
                return 1;
        return (a * llPowMod(a, n-1, mod)) % mod;
}

/* long long pow's */
unsigned long long ullPow(unsigned long long a, unsigned long long n) {
        if (n <= 0)
                return 1;
        return (a * ullPow(a, n-1));
}

long long int lliPow(long long int a, long long int n) {
        if (n <= 0)
                return 1;
        return (a * lliPow(a, n-1));
}

#ifdef NON_LIBRARY

int main(int argc, char **argv) {
        long long int a, n, m;
	if (argc != 4 && argc != 3) {
		printf("[%s] Usage: `%s [a] [n]' results in a^n\n", argv[0], argv[0]);
		printf("[%s] Usage: `%s [a] [n] [m]' results in a^n mod m\n", argv[0], argv[0]);
		exit(-1);
	}
        a = atoll(argv[1]);
        n = atoll(argv[2]);
	if (argc == 4) {
        	m = atoll(argv[3]);
        	printf("%lli^%lli mod %lli = %lli\n", a, n, m, llPowMod(a, n, m));
	} else {
        	printf("%lli^%lli = %lli\n", a, n, llPow(a, n));
	}
        return 0;
}

#endif
