#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; }