Open In App

Fibonacci Number modulo M and Pisano Period

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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:

i 0 1 2 3 4 5 6 7 8 9 10 11
Fi 0 1 1 2 3 5 8 13 21 34 55 89
Fi mod 2 0 1 1 0 1 1 0 1 1 0 1 1
Fi mod 3 0 1 1 2 0 2 2 1 0 1 1 2

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++




// 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 * m
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
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
int main()
{
    long n = 1548276540;
    long m = 235;
 
    cout << (fibonacciModulo(n, m));
    return 0;
}
 
// This code is contributed by subhammahato348


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))


C#




// C# program to calculate
// Fibonacci no. modulo m using
// Pisano Period
using 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.


Javascript




<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 * m
function 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 m
function 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>


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)

Auxiliary Space: O(1)
 



Last Updated : 29 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads