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 C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
#include <sstream>
#include <iomanip>
#include <numeric>
#define REP(i, n, s) for (int i = (s); i < (int)(n); i++)
#define REP0(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define ll long long
#define ALL(a) (a).begin(), (a).end()
using namespace std;

ll i, j;
const int MOD = 1000000000 + 7;
const int MOD2 = 998244353;

// modint: mod 計算を int を扱うように扱える構造体
template <int MOD>
struct Fp
{
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD)
    {
        if (val < 0)
            val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator-() const noexcept
    {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator+(const Fp &r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator-(const Fp &r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator*(const Fp &r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator/(const Fp &r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp &operator+=(const Fp &r) noexcept
    {
        val += r.val;
        if (val >= MOD)
            val -= MOD;
        return *this;
    }
    constexpr Fp &operator-=(const Fp &r) noexcept
    {
        val -= r.val;
        if (val < 0)
            val += MOD;
        return *this;
    }
    constexpr Fp &operator*=(const Fp &r) noexcept
    {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp &operator/=(const Fp &r) noexcept
    {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b)
        {
            long long t = a / b;
            a -= t * b;
            swap(a, b);
            u -= t * v;
            swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0)
            val += MOD;
        return *this;
    }
    constexpr bool operator==(const Fp &r) const noexcept
    {
        return this->val == r.val;
    }
    constexpr bool operator!=(const Fp &r) const noexcept
    {
        return this->val != r.val;
    }
    friend constexpr ostream &operator<<(ostream &os, const Fp<MOD> &x) noexcept
    {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept
    {
        if (n == 0)
            return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1)
            t = t * a;
        return t;
    }
};

using mint = Fp<MOD2>;

int main()
{
    ll n, x, m;
    ll ans = 0LL;

    cin >> n >> x >> m;

    vector<ll> list;
    vector<ll>::iterator itr;
    ll first_index = INT64_MAX;
    ll last_index = INT64_MAX;
    ll num = x;
    list.push_back(num);

    REP(i, n, 1LL)
    {
        num = (num * num) % m;
        itr = find(ALL(list), num);
        if (itr != list.end())
        {
            first_index = distance(list.begin(), itr); //ループ開始点
            last_index = i - 1LL;                        //ループ終了点
            break;
        }
        else
        {
            list.push_back(num);
        }
    }
    if (first_index == INT64_MAX && last_index == INT64_MAX)
    {
        REP(i, n, 0LL)
        {
            ans += list[i];
        }
    }
    else
    {
        ll pit = 0LL;

        REP(i, first_index, 0LL)
        {
            pit += list[i];
        }
        ll length = last_index - first_index + 1LL;
        ll wanted_index = (n - first_index) % length;
        ll cnt = (n - first_index) / length;

        ll set_list = accumulate(itr,list.end(),0LL);

        ans = pit + set_list * cnt;
        REP(i, first_index + wanted_index, first_index)
        {
            ans += list[i];
        }
    }

    // cout<<"pit:"<<pit<<"\n";
    // cout<<"set_list:"<<set_list<<"\n";
    // cout<<first_index<<" "<<last_index<<"\n";

    // cout<<"\n";

    cout << ans << '\n';
    return 0;
}