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 Rust (1.42.0) (judge verdict: Accepted)

use std::io::Read;

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();

    let answer = solve(&buf);

    println!("{}", answer);
}

fn solve(input: &str) -> String {
    let mut iterator = input.split_whitespace();

    let n: usize = iterator.next().unwrap().parse().unwrap();
    let x: usize = iterator.next().unwrap().parse().unwrap();
    let m: usize = iterator.next().unwrap().parse().unwrap();

    let mut sum: usize = 0;
    let mut history: Vec<usize> = Vec::new();
    let mut positions: Vec<usize> = vec![0; m];
    let mut current = x;
    sum += current;
    history.push(current);
    positions[current] = 1;
    let mut count: usize = 2;
    while count <= n {
        current = (current * current) % m;
        if positions[current] != 0 {
            let loops = count - positions[current];
            let rest = n - count + 1;
            let mut sum_of_loop = 0;
            for i in (positions[current] - 1)..(count - 1) {
                sum_of_loop += history[i];
            }
            sum += sum_of_loop * (rest / loops);
            for i in (positions[current] - 1)..(positions[current] - 1 + rest % loops) {
                sum += history[i];
            }
            break;
        }
        sum += current;
        history.push(current);
        positions[current] = count;
        count += 1;
    }
    sum.to_string()
}