Fibonacci Number modulo M and Pisano Period

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

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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

 # Python 3 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            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 calcuate FN modulo M.

Time Complexity: O(M2)

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Article Tags :
Practice Tags :

2

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.