#include <bits/stdc++.h>
using namespace std;
long long convert(const string &s) {
  long long ans = 0;
  for (int i = s.size() - 1, j = 0; i >= 0; --i, ++j)
    if (s[i] == '1') ans = ans | (1ULL << j);
  return ans;
}
long long correcting(long long x, const vector<int> &correct, int n) {
  for (int c : correct) x = x ^ (1ULL << c);
  return x;
}
bool hnext(vector<int> &correct, int n) {
  if (correct.empty()) return false;
  for (int i = correct.size() - 1, j = 0; i >= 0; --i, ++j) {
    int mx = n - 1 - j;
    if ((j > 0 && correct[i] + 1 != correct[i + 1]) || (correct[i] != mx)) {
      ++correct[i];
      for (int k = i + 1; k < correct.size(); ++k)
        correct[k] = correct[k - 1] + 1;
      return true;
    }
  }
  return false;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  unordered_set<long long> all;
  string s;
  int c;
  cin >> s >> c;
  long long num = convert(s);
  vector<int> correct;
  for (int i = 0; i < c; ++i) correct.push_back(i);
  do {
    long long temp = correcting(num, correct, n);
    all.insert(temp);
  } while (hnext(correct, n));
  for (int i = 1; i < m; ++i) {
    cin >> s >> c;
    unordered_set<long long> allthis;
    num = convert(s);
    correct.clear();
    for (int i = 0; i < c; ++i) correct.push_back(i);
    do {
      long long temp = correcting(num, correct, n);
      if (all.count(temp)) allthis.insert(temp);
    } while (hnext(correct, n));
    all = allthis;
  }
  cout << all.size() << "\n";
  return 0;
}
