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(unused_imports)]

use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::{i32, i64, i128, u32, u64, u128, f64};
use std::io::{stdout, Write, BufWriter};
use std::mem::{swap};
use proconio::{input, marker::{Isize1, Usize1, Bytes, Chars}};

#[proconio::fastout]
fn main() {
    input!(
        n: usize,
        x: i64,
        m: i64,
    );
    let mut hist = HashSet::new();
    let mut mods = Vec::with_capacity(m as usize);
    let mut looped = false;
    let mut i = 1;
    mods.push(x);
    while i < n {
        let r = (mods.last().unwrap()).pow(2) % m;
        if hist.contains(&r) {
            looped = true;
            mods.push(r);
            break;
        }
        else {
            hist.insert(r);
            mods.push(r);
        }
        i += 1;
    }
    if !looped { println!("{}", mods.into_iter().sum::<i64>()); }
    else {
        let start = mods.pop().unwrap();
        let startind = mods.iter().copied().position(|m| m == start).unwrap();
        let looplen = mods.len() - startind;
        let loopsum: i64 = mods[startind..].into_iter().sum();
        let remlen = n - startind;
        let ans = mods[..startind].into_iter().sum::<i64>();
        if remlen % looplen == 0 {
            println!("{}", ans + loopsum * ((remlen / looplen) as i64));
        } else {
            println!("{}", ans + loopsum * ((remlen / looplen) as i64) + mods[startind..(startind + (remlen % looplen))].into_iter().sum::<i64>());

        }
    }
}