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: Accepted)

/*
    Written by Kabir Kanha Arora
    @kabirkanha
 */

import java.util.*;

public class Main {
    public static void main(String[] args) {

        // Input
        Scanner scanner = new Scanner(System.in);
        long n = scanner.nextLong();
        long x = scanner.nextLong();
        long m = scanner.nextLong();

        HashMap<Long, Long> map = new HashMap<>();
        map.put(x, 0L);
        long curr = x;
        boolean zeroFlag = false;
        long loopStart = 0;
        long loopSize = 1;
        long loopStartElement = x;
        long sum = x;

        for (long i = 1; i < 1e7 && i < n; ++i) {
            curr = ((curr % m) * (curr % m)) % m;
            if (curr == 0) {
                zeroFlag = true;
                System.out.println(sum);
                break;
            }
            if (map.containsKey(curr)) {
                loopStart = map.get(curr);
                loopStartElement = curr;
                loopSize = i - loopStart;
                break;
            } else {
                sum += curr;
                map.put(curr, i);
                loopSize++;
            }
        }
        if (!zeroFlag) {

            // Elements before start of loop
            sum = 0;
            curr = x;
            long i;
            if (loopStart > 0)
                sum += x;
            for (i = 1; i < loopStart; ++i) {
                curr = ((curr % m) * (curr % m)) % m;
                sum += curr;
            }

            // Sum of loop elements
            long loopSum = loopStartElement;
            curr = loopStartElement;
            for (i = 1; i < loopSize; ++i) {
                curr = ((curr % m) * (curr % m)) % m;
                loopSum += curr;
            }
            long loops = (n - loopStart) / loopSize;
            sum += loops * loopSum;


            // Sum of remaining elements
            long rem = n - (loops * loopSize) - loopStart;
            if (rem > 0)
                sum += loopStartElement;
            curr = loopStartElement;
            for (i = 1; i < rem; ++i) {
                curr = ((curr % m) * (curr % m)) % m;
                sum += curr;
            }
            System.out.println(sum);
        }
    }
}