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 Fortran (GNU Fortran 9.2.1) (judge verdict: Wrong Answer)

module vector_int64_mod
    use,intrinsic :: iso_fortran_env
    implicit none
    private
    public:: vec_to_array, vec_size
    type,public:: vector_int64
        integer(int64),allocatable:: array(:)
        integer(int64),private:: l=0
    contains
        procedure:: push_back=>vec_push_back, insert=>vec_insert
        procedure:: pop_back=>vec_pop_back, pop=>vec_pop, erase => vec_erase
        procedure:: at=>vec_at, back=>vec_back, head=>vec_head
    end type
contains
    function vec_size(vec) result(ret)
        type(vector_int64),intent(in):: vec
        integer(int64):: ret

        ret = vec%l
    end function


    subroutine check_array_allocation(vec)
        type(vector_int64),intent(inout):: vec

        if (.not. allocated(vec%array)) allocate(vec%array(1))
    end subroutine


    function vec_at(vec,i) result(ret)
        class(vector_int64),intent(inout):: vec
        integer(int64):: i,ret

        call check_array_allocation(vec)
        ret = vec%array(i)
    end function


    function vec_back(vec) result(ret)
        class(vector_int64),intent(inout):: vec
        integer(int64):: ret
        
        ret = vec%at(vec%l)
    end function


    function vec_head(vec) result(ret)
        class(vector_int64),intent(inout):: vec
        integer(int64):: ret
        
        ret = vec%at(1_8)
    end function


    subroutine vec_append_array(vec,l,r)
        type(vector_int64),intent(inout):: vec
        integer(int64),intent(in):: l,r
        integer(int64),allocatable:: tmp(:)
        
        allocate(tmp(l:2*r))
        tmp(l:r) = vec%array(l:r)
        call move_alloc(tmp, vec%array)
    end subroutine


    subroutine vec_reduce_array(vec,l,r)
        type(vector_int64),intent(inout):: vec
        integer(int64),intent(in):: l,r
        integer(int64),allocatable:: tmp(:)
        
        allocate(tmp(l:r/2))
        tmp(l:r/2) = vec%array(l:r/2)
        call move_alloc(tmp, vec%array)
    end subroutine


    subroutine check_allocation_size(vec)
        type(vector_int64),intent(inout):: vec
        integer(int64):: len_alloc

        call check_array_allocation(vec)
        len_alloc = size(vec%array)
        if (vec%l >= len_alloc) then
            call vec_append_array(vec,1_8,len_alloc)
        else if (vec%l <= len_alloc/2) then
            call vec_reduce_array(vec,1_8,len_alloc)
        end if
    end subroutine


    subroutine vec_push_back(vec, v)
        class(vector_int64),intent(inout):: vec
        integer(int64),intent(in):: v

        vec%l=vec%l+1
        call check_allocation_size(vec)
        vec%array(vec%l) = v
    end subroutine


    subroutine vec_insert(vec,i,v)
        class(vector_int64),intent(inout):: vec
        integer(int64),intent(in)::i, v

        vec%l=vec%l+1
        call check_allocation_size(vec)
        vec%array(i+1:vec%l+1) = vec%array(i:vec%l)
        vec%array(i) = v
    end subroutine


    function vec_pop_back(vec) result(ret)
        class(vector_int64),intent(inout):: vec
        integer(int64):: ret

        ret = vec%back()
        vec%l=vec%l-1
        call check_allocation_size(vec)
    end function


    function vec_pop(vec,i) result(ret)
        class(vector_int64),intent(inout):: vec
        integer(int64),intent(in):: i
        integer(int64):: ret

        ret = vec%at(i)
        vec%l=vec%l-1
        vec%array(i:vec%l) = vec%array(i+1:vec%l+1)
        call check_allocation_size(vec)
    end function


    subroutine vec_erase(vec,i)
        class(vector_int64):: vec
        integer(int64),intent(in):: i
        integer(int64):: dmp

        dmp = vec%pop(i)
    end subroutine


    function vec_to_array(vec) result(ret)
        type(vector_int64),intent(inout):: vec
        integer(int64):: ret(1:vec%l)

        call check_array_allocation(vec)
        ret = vec%array(1:vec%l)
    end function
end module

program main
    use,intrinsic :: iso_fortran_env
    use vector_int64_mod
    implicit none
    integer(int64):: n,x,m
    integer(int64):: i,j,l,ln,tot=0,s=0,ans=0
    integer(int64), allocatable:: id(:)
    type(vector_int64):: a

    read*, n,x,m
    allocate(id(0:m),source=-1_8)

    j=1
    do while(id(x) == -1_8)
        call a%push_back(x)
        tot=tot+x
        id(x)=j
        x=mod(x*x,m)
        j=j+1
    end do
    l = j-id(x)
    do i=id(x),j-1
        s=s+a%at(i)
    end do
    
    if (n<j) then
        do i=1,n
            ans=ans+a%at(i)
        end do
    else
        ans=tot
        ln = ((n-(j-1))/l)*s
        ans=ans+ln
        do i=id(x),id(x)+mod((n-(j-1)),l)
            ans=ans+a%at(i)
        end do
    end if
    print'(i0)',  ans
end program main