Problem:
Score : 500 points

Problem Statement

Let us denote by f(x, m) the remainder of the Euclidean division of x by m.

Let A be the sequence that is defined by the initial value A_1=X and the recurrence relation A_{n+1} = f(A_n^2, M).
Find \displaystyle{\sum_{i=1}^N A_i}.

Constraints

1 \leq N \leq 10^{10}

0 \leq X < M \leq 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N X M

Output

Print \displaystyle{\sum_{i=1}^N A_i}.

Sample Input 1

6 2 1001

Sample Output 1

1369

The sequence A begins 2,4,16,256,471,620,\ldots Therefore, the answer is 2+4+16+256+471+620=1369.

Sample Input 2

1000 2 16

Sample Output 2

6

The sequence A begins 2,4,0,0,\ldots Therefore, the answer is 6.

Sample Input 3

10000000000 10 99959

Sample Output 3

492443256176507

Solution in Java (OpenJDK 11.0.6) (judge verdict: Runtime Error)

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        long n = sc.nextLong(); int x = sc.nextInt(); int m = sc.nextInt();
        if (n == 1) {
            out.println(0);
            out.close();
            return;
        } else if (n == 2) {
            if (x % 2 == 0) out.println(0);
            else out.println(n);
            out.close();
            return;
        }
        long [] c = new long[m - 2]; long cur = x;
        for (int i = 0; i < m - 2; i++) {
            c[i] = cur;
            cur = (cur * cur) % m;
        }
        //n--;
        if (n <= m - 3) {
            long res = 0;
            for (int i = 0; i < n; i++) {
                res = (res + c[i]);
            }
            out.println(res);
        } else {
            Map<Long, Integer> map = new HashMap<>();
            long a = 0; int start = -1; int end = -1;
            for (int i = 0; i <= m - 3; i++) {
                a += c[i];
                if (!map.containsKey(c[i])) map.put(c[i], i);
                else {
                    start = map.get(c[i]);
                    end = i;
                    break;
                }
            }
            if (c[m - 3] == 0) {
                out.println(a);
            } else {
                if (start == -1) {
                    start = 0; end = m - 2;
                }
                int len = end - start;
                long before = 0;
                for (int i = 0; i < start; i++) before = before + c[i];
                long times = (n - start) / len;
                long cycle = 0;
                for (int i = start; i < end; i++) cycle += c[i];
                long ret = cycle * times;
                long rem = (n - start) % len;
                for (int i = start; i < start + rem; i++) ret += c[i];
                ret += before;
                out.println(ret );
            }
        }
        out.close();
    }


    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }


    }

}