#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
// - Tính chất của số chính phương:
// Khi phân tích một số chính phương thành các thừa số nguyên tố thì số mũ của mỗi thừa số nguyên tố đều là số chẵn.
// - Có max{a(i)} <= 70 => Chỉ có 19 số nguyên tố <= 70
// => mask biểu diễn tính chẵn lẻ của số mũ các số nguyên tố
// (bit thứ i là 0: số nguyên tố thứ i (prime[i]) có số mũ là chẵn
// bit thứ i là 1: số nguyên tố thứ i (prime[i]) có số mũ là lẻ)
// => dp[i][mask] = Số tập con khác nhau khi xét i phần tử đầu tiên,
// với mask biểu diễn tính chẵn lẻ của số mũ các số nguyên tố trong phân tích thừa số của tích các phần tử có trong tập con
// => Độ phức tạp: O(n * 2^19)
// Tối ưu: Tận dụng max({a(i)}) <= 70 => DP theo giá trị thay vì theo chỉ số
// => dp[x][mask] = Số tập con khác nhau khi xét các giá trị từ 1 đến x,
// với mask biểu diễn ...
// => Công thức dp lúc này yêu cầu kiến thức về tổ hợp cũng như tính chất của phép xor
// - Tính chất phép xor:
// x ^ 0 = x
// x ^ x = 0
// - Tổ hợp: Số cách chọn chẵn/lẻ phần tử từ tập có n phần tử = 2^(n - 1)
// => Độ phức tạp: O(MAX_A * 2^19)
const int N = 1e5 + 5;
const int MAX_A = 70;
const int MOD = 1e9 + 7;
void add(int& a, int b) {
a += b;
if (a >= MOD) a -= MOD;
if (a < 0) a += MOD;
}
int prime[19] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67};
int n;
int a[N];
int cnt[MAX_A + 5]; // cnt[x] = Số lần xuất hiện của x trong mảng a
int pow2[N]; // pow2[i] = 2^i % MOD
int prime_mask[MAX_A + 5]; // prime_mask[x] = mask biểu diễn tính chẵn lẻ của số mũ các số nguyên tố trong phân tích thừa số của x
int dp[MAX_A + 5][1 << 19]; // dp[x][mask]
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
cnt[a[i]]++;
}
pow2[0] = 1;
for (int i = 1; i <= n; i++) pow2[i] = pow2[i - 1] * 2 % MOD;
for (int x = 1; x <= MAX_A; x++) {
int tmp = x;
for (int i = 0; i < 19; i++) {
int e = 0;
while (tmp % prime[i] == 0) {
tmp /= prime[i];
e += 1;
}
if (e & 1) prime_mask[x] |= (1 << i);
}
}
dp[0][0] = 1;
for (int x = 1; x <= MAX_A; x++) {
for (int prev_mask = 0; prev_mask < (1 << 19); prev_mask++) {
if (cnt[x] == 0) {
add(dp[x][prev_mask], dp[x - 1][prev_mask]);
}
else {
// Thêm vào tập hợp trước đó chẵn phần tử có giá trị là x
add(dp[x][prev_mask], 1ll * dp[x - 1][prev_mask] * pow2[cnt[x] - 1] % MOD);
// Thêm vào tập hợp trước đó lẻ phần tử có giá trị là x
add(dp[x][prev_mask ^ prime_mask[x]], 1ll * dp[x - 1][prev_mask] * pow2[cnt[x] - 1] % MOD);
}
}
}
int ans = dp[MAX_A][0];
add(ans, -1); // Trừ đi trường hợp tập rỗng
cout << ans << '\n';
}