1 ≤ N,M ≤ 1018
code using Fast Doubling
#include
#include
#include
using namespace std;
#define MAXN 60
#define MAXM 4
long long int M,N ;
long long F[MAXN][MAXM],FB[MAXN+5];
void readint(long long &a)
{
register int c;
a = 0;
do c = getchar_unlocked(); while(c < '0');
do{
a = (a << 1) + (a <= '0');
}
void printint(long long int a)
{
char s[21];
int t = -1;
do{
s[++t] = a % 10 + '0';
a /= 10;
}while(a > 0);
while(t >= 0)putchar_unlocked(s[t--]);
putchar_unlocked('\n');
}
long long int mulmod(long long int a,long long int b) {
long double res = a;
res *= b;
long long int c = (long long)(res / M);
a *= b;
a -= c * M;
a %= M;
if (a < 0) a += M;
return a;
}
long long int f(long long int n,int depth = 0 ) {
if(n<=MAXN){
return FB[n]%M ;
}
int val = n%4 ;
if (F[depth][val] != -1)
return F[depth][val];
long long int k=n >> 1;
long long int a,b,c;
a = f(k,depth+1) ;
b = f(k-1,depth+1) ;
if (n%2==0) {
F[depth][val] = (mulmod(a,a) + mulmod(b,b));
}else {
c = f(k+1,depth+1) ;
F[depth][val] = (mulmod(a,c) + mulmod(b,a));
}
if(F[depth][val] >= M)
F[depth][val] -= M ;
return F[depth][val] ;
}
int main(){
int T = 63450 ;
FB[0] = 1 ;
FB[1] = 1 ;
for(int i=2;i<=64;i++){
FB[i] = FB[i-1] + FB[i-2] ;
}
while(T--){
memset(F,-1,sizeof F) ;
readint(N) ;
readint(M) ;
printint((N==0 ? 0 : f(N-1))) ;
}
return 0 ;
}

