#include <bits/stdc++.h>

using namespace std;

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

const int N = 1111111;
int erat[N];

struct Dsu {
    int n;
    vector<int> p, rk;
    
    Dsu(int _n): n(_n), p(_n), rk(_n) {
        iota(p.begin(), p.end(), 0);
    }
    
    int get(int v) {
        return p[v] == v ? v : p[v] = get(p[v]);
    }
    
    bool merge(int u, int v) {
        u = get(u);
        v = get(v);
        if (u == v) {
            return false;
        }
        if (rk[v] > rk[u]) {
            swap(u, v);
        }
        p[v] = u;
        if (rk[u] == rk[v]) {
            ++rk[u];
        }
        return true;
    }
};

// Complete the solve function below.
int solve(vector<int> a) {
    int n = a.size();
    map<int, vector<int>> M;
    for (int i = 0; i < n; ++i) {
        int p = -1;
        while (a[i] > 1) {
            if (p != erat[a[i]]) {
                auto& v = M[erat[a[i]]];
                v.push_back(i);
            }
            p = erat[a[i]];
            a[i] /= p;
        }
    }
    Dsu dsu(n);
    for (const auto& p : M) {
        int last = -1;
        for (int v : p.second) {
            if (last > -1) {
                dsu.merge(last, v);
            }
            last = v;
        }
    }
    
    set<int> S;
    for (int i = 0; i < n; ++i) {
        S.insert(dsu.get(i));
    }
    int m = S.size();
    long long ans = 1;
    const int mod = 1000000007;
    for (int i = 0; i < m; ++i) {
        ans = ans * 2 % mod;
    }
    ans += mod - 2;
    return ans % mod;
}

int main()
{
    for (int n = 2; n < N; ++n) {
        if (erat[n]) {
            continue;
        }
        erat[n] = n;
        if (1.0 * n * n < N + N) {
            for (int i = n * n; i < N; i += n) {
                if (erat[i] == 0) {
                    erat[i] = n;
                }
            }
        }
    }
    
    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;
}