import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.InputMismatchException; import java.util.LinkedList; import java.util.Queue; import java.util.TreeSet; public class Main implements Runnable { static final long MOD = 1000000007L; static final long MOD2 = 1000000009L; static class InputReader { private InputStream stream; private byte[] buf = new byte[1024]; private int curChar; private int numChars; private SpaceCharFilter filter; private BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public InputReader(InputStream stream) { this.stream = stream; } public int read() { if (numChars==-1) throw new InputMismatchException(); if (curChar >= numChars) { curChar = 0; try { numChars = stream.read(buf); } catch (IOException e) { throw new InputMismatchException(); } if(numChars <= 0) return -1; } return buf[curChar++]; } public String nextLine() { String str = ""; try { str = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } public int nextInt() { int c = read(); while(isSpaceChar(c)) c = read(); int sgn = 1; if (c == '-') { sgn = -1; c = read(); } int res = 0; do { if(c<'0'||c>'9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = read(); } while (!isSpaceChar(c)); return res * sgn; } public long nextLong() { int c = read(); while (isSpaceChar(c)) c = read(); int sgn = 1; if (c == '-') { sgn = -1; c = read(); } long res = 0; do { if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = read(); } while (!isSpaceChar(c)); return res * sgn; } public double nextDouble() { int c = read(); while (isSpaceChar(c)) c = read(); int sgn = 1; if (c == '-') { sgn = -1; c = read(); } double res = 0; while (!isSpaceChar(c) && c != '.') { if (c == 'e' || c == 'E') return res * Math.pow(10, nextInt()); if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = read(); } if (c == '.') { c = read(); double m = 1; while (!isSpaceChar(c)) { if (c == 'e' || c == 'E') return res * Math.pow(10, nextInt()); if (c < '0' || c > '9') throw new InputMismatchException(); m /= 10; res += (c - '0') * m; c = read(); } } return res * sgn; } public String readString() { int c = read(); while (isSpaceChar(c)) c = read(); StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = read(); } while (!isSpaceChar(c)); return res.toString(); } public boolean isSpaceChar(int c) { if (filter != null) return filter.isSpaceChar(c); return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; } public String next() { return readString(); } public interface SpaceCharFilter { public boolean isSpaceChar(int ch); } } public static void main(String args[]) throws Exception { new Thread(null, new Main(),"Main",1<<26).start(); } int MAXN = 1000001; HashMap<Integer,HashMap<Integer,Integer>> adj; ArrayList<Temp> adj2[]; Integer[] arr; int[] dx = {1,-1,0,0}; int[] dy = {0,0,1,-1}; public void run() { InputReader sc= new InputReader(System.in); PrintWriter w= new PrintWriter(System.out); int t = sc.nextInt(); spf = new int[MAXN]; pre(); while(t-- > 0) { int n = sc.nextInt(); arr = new Integer[MAXN]; for(int i = 0;i < MAXN;i++) { arr[i] = i; } int[] temp = new int[MAXN]; Arrays.fill(temp, -1); int[] a = new int[n]; int val=0; for(int i = 0;i < n;i++) { a[i] = sc.nextInt(); if(a[i]==1) { val++; continue; } TreeSet<Integer> one = fact(a[i]); for(Integer x: one) { if(temp[x] != -1) { boolean res = find(temp[x],a[i]); if(!res) { union(temp[x],a[i]); } } temp[x] = a[i]; } } TreeSet<Integer> cnt = new TreeSet(); for(int i = 0;i < n;i++) { if(a[i]!=1) cnt.add(arr[root(a[i])]); } val += cnt.size(); if(val == 1 && cnt.first() == 1) { w.println(n); }else { long ans = (cnt2[val] - 2 + MOD) % MOD; w.println(ans); } } w.close(); } long modInverse(long a,long mod) { long temp = power(a, mod-2, mod); return temp; } int[] parent; long[] weight; static class Temp{ int a; long b; Temp(int a,long b){ this.a = a; this.b = b; } } long[] cnt2 = new long[MAXN]; boolean[] prime; void sieve() { prime = new boolean[MAXN]; Arrays.fill(prime, true); prime[1] = false; for(int i = 2;i < MAXN;i++) { if(prime[i]) { for(int j = 2*i;j < MAXN;j += i) { prime[j] = false; } } } } int[] spf; void pre() { cnt2[0] = 1; for(int i = 1;i < MAXN;i++) { cnt2[i] = (cnt2[i-1] * 2) % MOD; } spf = new int[MAXN]; for(int i = 1;i < MAXN;i++) { spf[i] = i; } for(int i = 2;i < MAXN;i += 2) { spf[i] = 2; } for(int i = 3;i * i < MAXN;i++) { if(spf[i] == i) { for(int j = 2*i;j < MAXN;j += i) { if(spf[j] == j) { spf[j] = i; } } } } } TreeSet<Integer> fact(int a){ TreeSet<Integer> tset = new TreeSet(); while(a != 1) { tset.add(spf[a]); a = a/spf[a]; } return tset; } long power(long a,long b,long mod) { long res = 1; a = a % mod; while(b > 0) { if(b % 2 == 1) { res = (res * a) % mod; } a = (a * a) % mod; b = b/2; } return res; } int[] ar; int root(int a) { while(arr[a] !=a) { arr[a] = arr[arr[a]]; a = arr[a]; } return a; } void union(int a,int b) { int root_a = root(a); int root_b = root(b); arr[root_a] = root_b; } boolean find(int a,int b) { int root_a = root(a); int root_b = root(b); return (root_a == root_b); } static class Pair implements Comparable<Pair>{ int a; int b; long c; Pair(int a,int b,long c){ this.a = a; this.b = b; this.c = c; } @Override public int compareTo(Pair o) { // TODO Auto-generated method stub return Long.compare(this.c,o.c); } } static class HopCroft{ private final int NIL = 0; private final int INF = Integer.MAX_VALUE; private ArrayList<Integer>[] Adj; private int[] Pair; private int[] Dist; private int cx, cy; public boolean BFS() { Queue<Integer> q = new LinkedList(); for(int v = 1;v <= cx;v++) { if(Pair[v] == NIL) { Dist[v] = 0; q.add(v); }else { Dist[v] = INF; } } Dist[NIL] = INF; while(!q.isEmpty()) { int v = q.poll(); if(Dist[v] < Dist[NIL]) { for(int u: Adj[v]) { if(Dist[Pair[u]] == INF) { Dist[Pair[u]] = Dist[v] + 1; q.add(Pair[u]); } } } } return Dist[NIL] != INF; } public boolean DFS(int v) { if(v != NIL) { for(int u: Adj[v]) { if(Dist[Pair[u]] == Dist[v] + 1) { if(DFS(Pair[u])) { Pair[u] = v; Pair[v] = u; return true; } } } Dist[v] = INF; return false; } return true; } public int HopcroftKarp() { Pair = new int[cx + cy + 1]; Dist = new int[cx + cy + 1]; int matching = 0; while(BFS()) { for(int v = 1;v <= cx;v++) { if(Pair[v] == NIL && DFS(v)) { matching++; } } } return matching; } public void makeGraph(int[] x,int[] y,int E) { Adj = new ArrayList[cx + cy + 1]; for (int i = 0; i < Adj.length; ++i) Adj[i] = new ArrayList<Integer>(); for (int i = 0; i < E; ++i) addEdge(x[i] + 1, y[i] + 1); } public void addEdge(int u,int v) { Adj[u].add(cx + v); Adj[cx + v].add(u); } } }