#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cmath>
#include<sstream>
#include<fstream>
#include<iomanip>
#include<ctime>
#include<complex>
#include<functional>
#include<climits>
#include<cassert>
#include<iterator>
#include<random>
#include<unordered_set>
#include<unordered_map>
using namespace std;

int t;

int n;

vector<int> v;
vector<int> primes;
vector<int> smallestPrimeFactor;
void linearSieve(int n) {
    if (n < 1) n = 1;
    if ((int)smallestPrimeFactor.size() >= n + 1) return;
    int primePiBound = n < 20 ? n - 1 : (int)(n / (log(n * 1.) - 2) + 2);
    primes.assign(primePiBound + 1, numeric_limits<int>::max());
    int P = 0;
    smallestPrimeFactor.assign(n + 1, 0);
    smallestPrimeFactor[1] = 1;
    int n2 = n / 2, n3 = n / 3, n5 = n / 5;
    if (n >= 2)
        primes[P++] = 2;
    if (n >= 3)
        primes[P++] = 3;
    for (int q = 2; q <= n; q += 2)
        smallestPrimeFactor[q] = 2;
    for (int q = 3; q <= n; q += 6)
        smallestPrimeFactor[q] = 3;
    for (int q = 5; q <= n5; q += 2) {
        if (smallestPrimeFactor[q] == 0)
            primes[P++] = smallestPrimeFactor[q] = q;
        int bound = smallestPrimeFactor[q];
        for (int i = 2;; ++i) {
            int p = primes[i];
            if (p > bound) break;
            int pq = p * q;
            if (pq > n) break;
            smallestPrimeFactor[pq] = p;
        }
    }
    for (int q = (n5 + 1) | 1; q <= n; q += 2) {
        if (smallestPrimeFactor[q] == 0)
            primes[P++] = smallestPrimeFactor[q] = q;
    }
    primes.resize(P);
}

map<int, vector<int> > mp;
struct UF{
    vector<int> belong;
    vector<int> size;
    void resize(int n){
        belong.assign(n + 1, -1);
        size.assign(n + 1, 1);
    }
    inline int root(int b){
        if (belong[b] == -1){
            return b;
        }
        belong[b] = root(belong[b]);
        return belong[b];
    }
    void merge(int a, int b){
        a = root(a);
        b = root(b);
        if (a == b)return;
        belong[a] = b;
        size[b] += size[a];
    }
};
UF uf;
#define MOD 1000000007
long long int ppow(long long int i, long long int j){
    long long int res = 1LL;
    while (j){
        if ((j & 1LL)){
            res *= i;
            if (res >= MOD){
                res %= MOD;
            }
        }
        j >>= 1;
        i *= i;
        if (i >= MOD){
            i %= MOD;
        }
    }
    return res;
}
int main(){
    cin >> t;
    linearSieve(1000002);
    while (t--){
        uf = UF();
        scanf("%d", &n);
        uf.resize(n);
        v.clear();
        for (int i = 0; i < n; i++){
            int a;
            scanf("%d", &a);
            v.push_back(a);
        }
        mp.clear();
        for (int i = 0; i < v.size(); i++){
            while (v[i]>1){
                mp[smallestPrimeFactor[v[i]]].push_back(i);
                v[i] /= smallestPrimeFactor[v[i]];
            }
        }
        for (auto &it : mp){
            for (int j = 0; j < it.second.size(); j++){
                uf.merge(it.second[j], it.second[0]);
            }
        }
        int sz = 0;
        for (int i = 0; i < n; i++){
            if (uf.root(i) == i){
                sz++;
            }
        }
        long long int ans = ppow(2, sz);
        ans -= 2LL;
        printf("%lld\n", ans);
    }
    return 0;
}