Fibonacci LCM
Difficulty: Hard

After Derek (of district 5) discovered how to compute the greatest common divisor (gcd) of Fibonacci numbers, he now tried to answer the next obvious question: how does one compute the *least common multiple* (lcm) of Fibonacci numbers? Unfortunately, Derek found out that this wasn't as easy as the original problem, so he asked you to answer it for him.

The Fibonacci numbers are defined as:

$$F_1 = F_2 = 1$$
$$F_n = F_{n-1} + F_{n-2}$$

Given $N$ integers $a_1, a_2, \ldots, a_N$, find $\text{lcm}(F_{a_1},F_{a_2},\ldots,F_{a_N})$, and give your answer modulo $10^9+7$.

**Input Format**  
The first line of input contains $N$.  
Each of the next $N$ lines contains a number: the $i^{\text{th}}$ line contains $a_i$.

**Constraints**  
$1 \le N \le 100$  
$1 \le a_i \le 10^9$  

**Output Format**  
Print a single integer, which is the least common multiple of the $F_{a_i}$, modulo $10^9+7$.

**Sample Input**  

    5
    1
    3
    3
    6
    9

**Sample Output**  

    136
    
**Explanation**  
$\text{lcm}(F_1,F_3,F_3,F_6,F_9) = \text{lcm}(1,2,2,8,34) = 136$  


Input Format:

Output Format:

Sample Input:

Sample Output:

Python 3 starter code:
#
# Complete the 'solve' function below.
#
# The function is expected to return an INTEGER.
# The function accepts INTEGER_ARRAY f as parameter.
#

def solve(f):
    # Write your code here




Reference solution (C++):
###C++  
```cpp  
#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <string>
#include <ctime>
#include <unordered_map>
#include <unordered_set>
#define M 1000000007

using namespace std;

int n,a[200],i,res[2];
unordered_map<int,int>fibs;

int gcd(int a,int b)
{
    if(a && b)
        while(a%=b^=a^=b^=a);
    return a+b;
}

int getFib(int n)
{
    auto it=fibs.find(n);
    if(it!=fibs.end()) return it->second;
    int a[2][2];
    int b[2];
    int temp[2];
    int c[2][2];
    int i,j;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
            a[i][j]=i||j;
        b[i]=i;
    }
    while(n)
    {
        if(n%2)
        {
            for(j=0;j<2;j++)
                temp[j]=((long long)b[0]*a[0][j]+(long long)b[1]*a[1][j])%M;
            for(j=0;j<2;j++)
                b[j]=temp[j];
        }
        for(i=0;i<2;i++)
            for(j=0;j<2;j++)
                c[i][j]=((long long)a[i][0]*a[0][j]+(long long)a[i][1]*a[1][j])%M;
        for(i=0;i<2;i++)
            for(j=0;j<2;j++)
                a[i][j]=c[i][j];
        n/=2;
    }
    return b[0];
}

void rec(int i,int ans,int isZ)
{
    if(i==n && ans) 
    {
        res[isZ]=(long long)res[isZ]*getFib(ans)%M;
        return;
    }
    int g=gcd(ans,a[i]);
    if(g==ans)return;
    rec(i+1,ans,isZ);
    rec(i+1,g,!isZ);
}

int obr(int x)
{
    int p=M,a=0,b=1,q;
    while(x)
    {
        q=p/x;
        p-=x*q;
        a-=b*q;
        p^=x^=p^=x;
        a^=b^=a^=b;
    }
    return (a+M)%M;
}

int main()
{
    scanf("%d",&n);
    if(n<1 || n>100)throw;    
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]<1 || a[i]>1000000000)throw;
    }
    sort(a,a+n);
    n=unique(a,a+n)-a;
    res[0]=res[1]=1;
    rec(0,0,1);
    res[0]=(long long)res[0]*obr(res[1])%M;
    printf("%d\n",res[0]);
    return 0;
}
```