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# (Mono-mcs 6.8.0.105) (judge verdict: Runtime Error)

using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
	//Main
	static void Main(string[] args)
	{
		//読み込む
		string[] S = Console.ReadLine().Split(' ');
		long N = long.Parse(S[0]);
		long X = long.Parse(S[1]);
		long M = long.Parse(S[2]);

		if(X == 0){
			Console.WriteLine(0);
			return;
		}
		if(X == 1){
			Console.WriteLine(N*(N-1)/2);
			return;
		}

		long loopIn = 0;
		long loopOut = 0;
		bool beOut = false;
		bool zero = false;

		int limit = 10000000;

		bool[] appear = new bool[M];

		long[] An = new long[limit];
		An[0] = X;
		long[] cumsum = new long[limit];
		cumsum[0] = An[0];

		for(int i=1; i<N; i++){
			An[i] = (An[i-1] * An[i-1]) % M;
			cumsum[i] = cumsum[i-1] + An[i];


			if(An[i] == 0){
				loopOut = i;
				zero = true;
				beOut = true;
				break;
				}

			if(appear[An[i]]){
				//Console.WriteLine("An[{0}]={1}",i,An[i]);
				loopIn = Array.IndexOf(An,An[i]);
				loopOut = i;
				beOut = true;
				break;
			}
			else{
				appear[An[i]] = true;
			}
		}

		long ans = 0;

		if(beOut){
			if(zero){
				ans = cumsum[loopOut-1];
			}
			else{
				ans += cumsum[loopOut-1];

				long div = (N-loopOut) / (loopOut-loopIn);
				long rem = (N-loopOut) % (loopOut-loopIn);

				long left = 0;
				if(loopIn - 1 < 0){
					left = 0;
				}
				else{
					left = cumsum[loopIn-1];
				}

				ans += ((cumsum[loopOut-1] - left) * div);
				ans += (cumsum[loopIn-1+rem] - left);
			}
		}
		else{
			ans = cumsum[N-1];
		}

		Console.WriteLine(ans);

		/*
		for(int i=0; i<N; i++){
			Console.Write("An[{0}]={1}, ", i,An[i]);
		}
		Console.WriteLine("");

		for(int i=0; i<N; i++){
			Console.Write("cumsum[{0}]={1}, ", i,cumsum[i]);
		}
		Console.WriteLine("");
		*/
	}
}