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::cmp;
use std::fmt::Debug;
use std::str::FromStr;
#[allow(dead_code)]
fn read_as_vec<T>() -> Vec<T>
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim()
        .split_whitespace()
        .map(|c| T::from_str(c).unwrap())
        .collect()
}

#[allow(dead_code)]
fn read_as_string() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

fn go_next(cur: usize, m: usize) -> usize {
    return (cur * cur) % m;
}

// returns (start, length before loop, loop length)
fn detect_loop(s: usize, m: usize) -> (usize, usize, usize) {
    let mut cur_cost = 0;
    let dummy = std::usize::MAX;
    let mut last_visited: Vec<usize> = vec![dummy; m];
    last_visited[s] = cur_cost;
    let mut cur = s;

    while last_visited[go_next(cur, m)] == dummy {
        cur_cost += 1;
        cur = go_next(cur, m);
        last_visited[cur] = cur_cost;
    }

    let loop_len = cur_cost + 1 - last_visited[go_next(cur, m)];
    return (go_next(cur, m), cur_cost + 1 - loop_len, loop_len);
}

fn calc_score(s: usize, len: usize, m: usize) -> usize {
    let mut score = 0;
    let mut cur = s;
    for _ in 0..len {
        score += cur;
        cur = go_next(cur, m);
    }

    return score;
}

fn main() {
    let line: Vec<usize> = read_as_vec::<usize>();
    let (n, x, m) = (line[0], line[1], line[2]);

    let (loop_entry, till_loop, loop_len) = detect_loop(x, m);
    dbg!(loop_entry, till_loop, loop_len);
    if n <= till_loop {
        println!("{}", calc_score(x, n, m));
        return;
    }

    // score before loop;
    let mut score = calc_score(x, till_loop, m);

    // calculate score loop * #loop;
    let rest = n - till_loop;
    score += rest / loop_len * calc_score(loop_entry, loop_len, m);

    let rest = rest % loop_len;

    score += calc_score(loop_entry, rest, m);

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