package tetration; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println(solve(sc.nextInt(),sc.nextInt(),sc.nextInt())); } static final int M_MAX = 2010; static int bmax = 0; static ArrayList hyper4Small; static int[] memo = new int[M_MAX]; //周期の計算用 public static long solve(long a,long b,long m) { if (a == 1) { return 1 % m; } /* * 小さいbに対して、hyper4(a,b)を愚直に計算する。 * hyper4(a,b) < M_MAXとなる最大のb,bmaxを求める。 * a = 1の場合そのようなbは存在しないのであらかじめ弾く。 */ hyper4Small = new ArrayList<>(); hyper4Small.add(1L); LOOP: for(int i=1;;i++) { long x = 1; long exponent = hyper4Small.get(i-1); for(int j=0;j= M_MAX) { break LOOP; } } hyper4Small.add(x); } bmax = hyper4Small.size() - 1; return hyper4Mod(a, b, m); } public static long hyper4Mod(long a,long b,long m) { //自明なケース if (m == 1) { return 0; } if (b == 0) { return 1; } if (b - 1 <= bmax) { //hyper4(a,b-1) <= M_MAX と同じ //前計算を用いる return powMod(a, hyper4Small.get((int)b-1) , m); }else{ //powmodの周期性を用いる long c = cycle(a,m); return powMod(a, M_MAX + mod((hyper4Mod(a, b-1, c) - M_MAX), c), m); } } /** * 1,a,a^2,a^3,... (mod m) がループする周期を求める。 * 例えばa=2,m=28のとき、 * 1,2,4,8,16,4,8,16,... * で返り値は3となる。 */ public static long cycle(long a,long m) { Arrays.fill(memo, -1); long x = powMod(a,M_MAX,m); for(int i=0;;i++) { int j = memo[(int) x]; if (j >= 0) { return i - j; } memo[(int) x] = i; x = x * a % m; } } public static long powMod(long x,long n,long mod) { long res = 1; while(n > 0) { if ((n & 1) > 0) { res = (res * x) % mod; } x = (x * x) % mod; n/=2; } return res; } public static long mod(long x,long m) { x %= m; if (x < 0) { x += m; } return x; } }