public class XorCards {
public long NumberOfSolution(int[,] matrix) {
int n = matrix.GetLength(0);
int m = matrix.GetLength(1);
bool[] used = new bool[n];
for (int i = 0; i < m; i++) {
int target = -1;
for (int j = 0; j < n; j++) {
if (!used[j] && matrix[j, i] == 1) { target = j; break; }
}
if (target == -1) continue;
used[target] = true;
for (int j = 0; j < n; j++) {
if (target == j) continue;
if (matrix[j, i] == 0) continue;
for (int k = 0; k < m; k++) {
matrix[j, k] ^= matrix[target, k];
}
}
}
int rank = 0;
for (int i = 0; i < n; i++) {
bool allZero = true;
for (int j = 0; j < m - 1; j++) {
if (matrix[i, j] == 1) { allZero = false; break; }
}
if (allZero) {
if (matrix[i, m - 1] == 1) return 0;
} else {
rank++;
}
}
return 1L << ((m - 1) - rank);
}
public long numberOfWays(long[] number, long limit) {
const int MaxBit = 60;
long ans = 0;
int n = number.Length;
limit ++;
for (int i = 0; i <= MaxBit; i++) {
if ((limit & (1L << i)) == 0) continue;
var array = new int[MaxBit + 1, n + 1];
for (int j = i ; j <= MaxBit; j++) {
if (i == j) array[j, n] = 0;
else array[j, n] = (limit & (1L << j)) != 0 ? 1 : 0;
for (int k = 0; k < n; k++) {
array[j, k] = (number[k] & (1L << j)) != 0 ? 1 : 0;
}
}
ans += NumberOfSolution(array);
}
return ans;
}
}