Skip to content
Related Articles

Related Articles

Fibonacci Number modulo M and Pisano Period
  • Difficulty Level : Medium
  • Last Updated : 12 Oct, 2020

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:

i01234567891011
Fi01123581321345589
Fi mod 2011011011011
Fi mod 3011202210112

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 in Python:

Java




// Java program to calculate
// Fibonacci no. modulo m using
// Pisano Period
import java.io.*;
 
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(String[] args)
{
    long n = 1548276540;
    long m = 235;
     
    System.out.println(fibonacciModulo(n, m));
}
}
 
// This code is contributor by Parag Pallav Singh

Python3




# 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 * m
def 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 m
def 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 Code
if __name__ == '__main__':
    n = 1548276540
    m = 235
    print(fibonacciModulo(n, m))
Output: 
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)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :