Fibonacci Number modulo M and Pisano Period

29 Mar, 2022
Given two number N and M. The task is to find the N-th fibonacci number mod M.In general let FN be the N-th fibonacci number then the output should be FN % M.
The Fibonacci sequence is a series of numbers in which each no. is the sum of two preceding nos. It is defined by the recurrence relation: 
F0 = 0
F1 = 1
Fn = Fn-1 + Fn-2
These nos. are in the following sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...Here N can be large.
Examples: 
Input: N = 438, M = 900 Output: 44
Input: N = 1548276540, M = 235 Output: 185  
Approach: However, for such values of N, a simple recursive approach to keep calculating N Fibonacci numbers with a time complexity of O(2N) should be avoided. Even an iterative or a Dynamic Programming approach with an algorithm looping for N iterations will not be time-efficient.This problem can be solved using the properties of Pisano Period. For a given value of N and M >= 2, the series generated with Fi modulo M (for i in range(N)) is periodic. 
The period always starts with 01. The Pisano Period is defined as the length of the period of this series.To understand it further, let’s see what happens when M is small:
For M = 2, the period is 011 and has length 3 while for M = 3 the sequence repeats after 8 nos.
Example: So to compute, say F2019 mod 5, we’ll find the remainder of 2019 when divided by 20 (Pisano Period of 5 is 20). 2019 mod 20 is 19. Therefore, F2019 mod 5 = F19 mod 5 = 1. This property is true in general. We need to find the remainder when N is divided by the Pisano Period of M. Then calculate F(N)remainder mod M for the newly calculated N.
Below is the implementation of FN modulo M:
C++
Java
Python3
C#
Javascript
// C++ program to calculate// Fibonacci no. modulo m using// Pisano Period#include <bits/stdc++.h>using namespace std; // Calculate and return Pisano Period// The length of a Pisano Period for// a given m ranges from 3 to m * mlong pisano(long m){    long prev = 0;    long curr = 1;    long res = 0;     for(int i = 0; i < m * m; i++)    {        long temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;         if (prev == 0 && curr == 1)            res = i + 1;    }    return res;} // Calculate Fn mod mlong fibonacciModulo(long n, long m){         // Getting the period    long pisanoPeriod = pisano(m);     n = n % pisanoPeriod;     long prev = 0;    long curr = 1;     if (n == 0)        return 0;    else if (n == 1)        return 1;     for(int i = 0; i < n - 1; i++)    {        long temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;    }    return curr % m;} // Driver Codeint main(){    long n = 1548276540;    long m = 235;     cout << (fibonacciModulo(n, m));    return 0;} // This code is contributed by subhammahato348
// Java program to calculate// Fibonacci no. modulo m using// Pisano Periodimport java.io.*; class GFG{     // Calculate and return Pisano Period// The length of a Pisano Period for// a given m ranges from 3 to m * mpublic static long pisano(long m){    long prev = 0;    long curr = 1;    long res = 0;         for(int i = 0; i < m * m; i++)    {        long temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;                 if (prev == 0 && curr == 1)            res= i + 1;    }    return res;} // Calculate Fn mod mpublic static long fibonacciModulo(long n,                                   long m){         // Getting the period    long pisanoPeriod = pisano(m);         n = n % pisanoPeriod;         long prev = 0;    long curr = 1;         if (n == 0)        return 0;    else if (n == 1)        return 1;         for(int i = 0; i < n - 1; i++)    {        long temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;    }    return curr % m;} // Driver Codepublic static void main(String[] args){    long n = 1548276540;    long m = 235;         System.out.println(fibonacciModulo(n, m));}} // This code is contributor by Parag Pallav Singh
# Python3 program to calculate# Fibonacci no. modulo m using# Pisano Period # Calculate and return Pisano Period# The length of a Pisano Period for# a given m ranges from 3 to m * mdef pisanoPeriod(m):    previous, current = 0, 1    for i in range(0, m * m):        previous, current \        = current, (previous + current) % m                 # A Pisano Period starts with 01        if (previous == 0 and current == 1):            return i + 1 # Calculate Fn mod mdef fibonacciModulo(n, m):         # Getting the period    pisano_period = pisanoPeriod(m)         # Taking mod of N with    # period length    n = n % pisano_period         previous, current = 0, 1    if n==0:        return 0    elif n==1:        return 1    for i in range(n-1):        previous, current \        = current, previous + current             return (current % m) # Driver Codeif __name__ == '__main__':    n = 1548276540    m = 235    print(fibonacciModulo(n, m))
// C# program to calculate// Fibonacci no. modulo m using// Pisano Periodusing System; class GFG {     // Calculate and return Pisano Period    // The length of a Pisano Period for    // a given m ranges from 3 to m * m    public static long pisano(long m)    {        long prev = 0;        long curr = 1;        long res = 0;         for (int i = 0; i < m * m; i++) {            long temp = 0;            temp = curr;            curr = (prev + curr) % m;            prev = temp;             if (prev == 0 && curr == 1)                res = i + 1;        }        return res;    }     // Calculate Fn mod m    public static long fibonacciModulo(long n, long m)    {         // Getting the period        long pisanoPeriod = pisano(m);         n = n % pisanoPeriod;         long prev = 0;        long curr = 1;         if (n == 0)            return 0;        else if (n == 1)            return 1;         for (int i = 0; i < n - 1; i++) {            long temp = 0;            temp = curr;            curr = (prev + curr) % m;            prev = temp;        }        return curr % m;    }     // Driver Code    public static void Main()    {        long n = 1548276540;        long m = 235;         Console.Write(fibonacciModulo(n, m));    }} // This code is contributed by subham348.
<script> // javascript program to calculate// Fibonacci no. modulo m using// Pisano Period// Calculate and return Pisano Period// The length of a Pisano Period for// a given m ranges from 3 to m * mfunction pisano(m){    let prev = 0;    let curr = 1;    let res = 0;     for(let i = 0; i < m * m; i++)    {        let temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;         if (prev == 0 && curr == 1)            res = i + 1;    }    return res;} // Calculate Fn mod mfunction fibonacciModulo(n,m){         // Getting the period    let pisanoPeriod = pisano(m);     n = n % pisanoPeriod;     let prev = 0;    let curr = 1;     if (n == 0)        return 0;    else if (n == 1)        return 1;     for(let i = 0; i < n - 1; i++)    {        let temp = 0;        temp = curr;        curr = (prev + curr) % m;        prev = temp;    }    return curr % m;}      let n = 1548276540;    let m = 235;     document.write(fibonacciModulo(n, m));         // This code is contributed by vaibhavrabadiya117.</script>
185
 
Pisano Period of 235 is 160. 1548276540 mod 160 is 60. F60 mod 235 = 185. Using Pisano Period, we now need to calculate Fibonacci nos. iteratively for a relatively lower N than specified in the original problem and then calculate FN modulo M.Time Complexity: O(M2)
Auxiliary Space: O(1) 
devkapilbansal
ParagPallavSingh1
subham348
subhammahato348
vaibhavrabadiya117
Fibonacci
Mathematical
Mathematical
Fibonacci
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.