#include <bits/stdc++.h>

#define mod 1000000007

using namespace std;

string ltrim(const string &);
string rtrim(const string &);
vector<string> split(const string &);

long long add(long long a, long long b) {
    a += b;
    if(a >= mod) return a - mod;
    return a;
}

long long mul(long long a, long long b) {
    return (a * b) % mod;
}

long long power(long long a, long long b) {
    if(b == 0) return 1;
    long long foo = power(a, b/2);
    foo = mul(foo, foo);
    if(b&1) return mul(a, foo);
    return foo;
}

class UnionFind {
    public:
        vector <int> p, rank;
        UnionFind() {}
        UnionFind(int N) {
            rank.assign(N, 0);
            p.assign(N, 0);
            for(int i = 0; i < N; i++) p[i] = i;
        }
        int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
        bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
        void unionSet(int i, int j) {
            if(!isSameSet(i, j)) {
                int x = findSet(i), y = findSet(j);
                if(rank[x] > rank[y]) {
                    p[y] = x;
                }
                else {
                    p[x] = y;
                    if(rank[x] == rank[y]) rank[y]++;
                }
            }
        }
} uf;

set <int> st;
map <int, int> mp;

int solve(vector <int> a) {
    st.clear();
    mp.clear();
    int n = a.size(), cnt = 0;
    vector <int> g[n];
    for(int i=0; i<n; i++) {
        if(a[i] == 1) {
            cnt++;
            continue;
        }
        if(a[i]%2 == 0) {
            g[i].push_back(2);
            while(a[i] % 2 == 0) a[i] /= 2;
            st.insert(2);
        }
        for(int j=3; j*j <= a[i]; j+=2) {
            if(a[i]%j == 0) {
                g[i].push_back(j);
                while(a[i] % j == 0) a[i] /= j;
                st.insert(j);
            }
        }
        if(a[i] > 1) {
            g[i].push_back(a[i]);
            st.insert(a[i]);
        }
    }
    int xx=0;
    for(int e : st) mp[e] = xx++;
    uf = UnionFind(st.size());
    for(int i=0; i<n; i++) {
        for(int j=0; j<g[i].size(); j++) {
            for(int k=j+1; k<g[i].size(); k++) {
                uf.unionSet(mp[g[i][j]], mp[g[i][k]]);
            }
        }
    }
    for(int i=0; i<st.size(); i++) if(uf.p[i] == i) cnt++;
    return (power(2, cnt) + mod - 2) % mod;
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string t_temp;
    getline(cin, t_temp);

    int t = stoi(ltrim(rtrim(t_temp)));

    for (int t_itr = 0; t_itr < t; t_itr++) {
        string a_count_temp;
        getline(cin, a_count_temp);

        int a_count = stoi(ltrim(rtrim(a_count_temp)));

        string a_temp_temp;
        getline(cin, a_temp_temp);

        vector<string> a_temp = split(rtrim(a_temp_temp));

        vector<int> a(a_count);

        for (int i = 0; i < a_count; i++) {
            int a_item = stoi(a_temp[i]);

            a[i] = a_item;
        }

        int result = solve(a);

        fout << result << "\n";
    }

    fout.close();

    return 0;
}

string ltrim(const string &str) {
    string s(str);

    s.erase(
        s.begin(),
        find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
    );

    return s;
}

string rtrim(const string &str) {
    string s(str);

    s.erase(
        find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
        s.end()
    );

    return s;
}

vector<string> split(const string &str) {
    vector<string> tokens;

    string::size_type start = 0;
    string::size_type end = 0;

    while ((end = str.find(" ", start)) != string::npos) {
        tokens.push_back(str.substr(start, end - start));

        start = end + 1;
    }

    tokens.push_back(str.substr(start));

    return tokens;
}