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  
#include <stdio.h>
#include <stdlib.h>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <algorithm>
#define mod 1000000007
#define L 10000000
#define ll long long
using namespace std;

ll ipow(ll b, ll e) {
    if (e == 1) return b;
    if (e & 1) return ipow(b, e - 1) * b % mod;
    return ipow(b * b % mod, e >> 1);
}
ll rx, ry;
void mmul(ll c, ll d, ll g, ll h) {
    ll dh = d * h;
    rx = ((c + d) * (g + h) - dh) % mod;
    ry = (c * g + dh) % mod;
}

void mpow(int e) {
    if (e == 1) {
        rx = 1;
        ry = 0;
    } else if (e & 1) {
        mpow(e - 1);
        mmul(1, 0, rx, ry);
    } else {
        mpow(e >> 1);
        mmul(rx, ry, rx, ry);
    }
}

ll F[L];

ll Fm(int n) {
    if (n < L) {
        return F[n];
    }
    mpow(n);
    return rx;
}

#define umap tr1::unordered_map
#define uset tr1::unordered_set

uset<int> dset;
uset<int> a;
int cs[311111];
int ds[311111];
int k;

int main() {


    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int v;
        scanf("%d", &v);
        a.insert(v);
    }

    F[0] = 0, F[1] = 1;
    for (int i = 2; i < L; i++) {
        F[i] = F[i-1] + F[i-2];
        if (F[i] >= mod) F[i] -= mod;
    }

    for (uset<int>::iterator it = a.begin(); it != a.end(); it++) {
        int x = *it;
        if (x <= 2) {
            continue;
        }
        for (int d = 1; d * d <= x; d++) {
            if (x % d == 0) {
                dset.insert(d);
                dset.insert(x / d);
            }
        }
    }

    k = 0;
    for (uset<int>::iterator it = dset.begin(); it != dset.end(); it++) {
        int key = *it;
        ds[k++] = key;
    }
    sort(ds, ds + k);

    ll ans = 1;
    for (int i = k-1; i >= 0; i--) {
        cs[i] = 1;
        for (int j = k-1; j > i; j--) {
            if (!(ds[j] % ds[i])) {
                cs[i] -= cs[j];
            }
        }

        int c = cs[i] % (mod-1);
        if (c < 0) c += mod-1;
        if (c) {
            ll f = Fm(ds[i]);
            if (f != 1) {
                ans *= ipow(f, c);
                ans %= mod;
            }
        }
    }

    if (ans < 0) ans += mod;
    printf("%lld\n", ans);
}
```