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)

#![allow(non_snake_case)]
#![allow(unused_imports)]
use proconio::input;
use std::cmp::max;
use std::cmp::min;
use std::collections::HashMap;
use std::collections::VecDeque;

#[allow(dead_code)]
fn solve_naive(N: usize, X: i64, M: i64) -> i64 {
    let mut ans: i64 = X;

    let mut prev = X;
    for _i in 2..=N {
        let current = (prev * prev) % M;
        ans += current;
        prev = current;
    }

    return ans;
}

fn main() {
    input! {
        N: usize,
        X: i64,
        M: i64,
    }

    // rests[i] = i * i % M;
    // let mut rests = vec![0i64; M];
    // for m in 0..M {
    //     rests[m as usize] = (m * m) % M;
    // }

    // ループを探そう
    let mut loops = vec![X];
    let mut is_visited: Vec<bool> = vec![false; M as usize];
    is_visited[X as usize] = true;
    let mut prev = X;
    // dbg!(prev);

    // 最大M回
    loop {
        let current = (prev * prev) % M;

        if is_visited[current as usize] {
            // 後で使えるようにするため、ループの出発点をprevに入れておく
            prev = current;
            break;
        }

        // dbg!(current);

        loops.push(current);
        is_visited[current as usize] = true;
        prev = current;
    }

    // ループの開始点
    // dbg!(prev);

    let mut ans: i64 = 0;
    let mut rest: usize = N;

    let mut true_loops = vec![];

    // まずループ開始点に辿り着く前まで
    let mut is_in_loop = false;
    for &a2 in loops.iter() {
        if a2 == prev {
            is_in_loop = true;
        }

        if is_in_loop {
            true_loops.push(a2);
        } else {
            ans += a2;
            rest -= 1;
        }
    }

    // できるだけloop
    let loop_sum: i64 = true_loops.iter().sum();
    let n: i64 = (rest / true_loops.len()) as i64;
    ans += loop_sum * n;
    rest -= true_loops.len() * n as usize;

    // 残りやる
    for i in 0..rest {
        let a2 = true_loops[i];
        ans += a2;
    }

    // let mut prev = X;
    // for _i in 2..=N {
    //     let current = (prev * prev) % M;
    //     ans += current;
    //     prev = current;
    // }

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