#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> size;
  vector<int> par;

 public:
  UnionFind(int n) : size(n, 1), par(n) {
    for (int i = 0; i < n; i++) par[i] = i;
  }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return;
    if (size[x] < size[y]) {
      par[x] = y;
      size[y] += size[x];
    } else {
      par[y] = x;
      size[x] += size[y];
    }
  }
  int find(int x) { return par[x] == x ? x : (par[x] = find(par[x])); }
};
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  vector<int> a(m);
  for (int i = 0; i < m; i++) {
    scanf("%d", &a[i]);
  }
  vector<int> isA(1 << n, false);
  for (int i = 0; i < m; i++) isA[a[i]] = true;
  vector<int> dp(1 << n, -2);
  UnionFind u(1 << n);
  int filter = (1 << n) - 1;
  function<int(int)> dfs = [&](int bit) {
    if (dp[bit] != -2) return dp[bit];
    if (bit == 0) return dp[bit] = (isA[0] ? 0 : -1);
    int v = isA[bit] ? bit : -1;
    for (int i = 0; i < n; i++) {
      if ((bit >> i) & 1) {
        int tob = bit ^ (1 << i);
        int nex = dfs(tob);
        if (v != -1 && nex != -1) {
          u.unite(v, nex);
        }
        if (v == -1) v = nex;
      }
    }
    return dp[bit] = v;
  };
  for (int i = 0; i < m; i++) {
    int bit = (~a[i]) & filter;
    int v = dfs(bit);
    if (v != -1) {
      u.unite(a[i], v);
    }
  }
  int res = 0;
  for (int i = 0; i < m; i++) {
    res += (int)(u.find(a[i]) == a[i]);
  }
  printf("%d\n", res);
  return 0;
}
