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