#include <bits/stdc++.h>
using namespace std;
int const N = 22, M = 1 << 22;
inline int nextInt() {
  char c;
  c = getchar();
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  int n = 0, s = 1;
  if (c == '-') s = -1, c = getchar();
  while (c >= '0' && c <= '9') n *= 10, n += c - '0', c = getchar();
  return n * s;
}
int mx;
int parents[M];
int Find(int a) { return parents[a] < 0 ? a : parents[a] = Find(parents[a]); }
void Union(int a, int b) {
  a = Find(a), b = Find(b);
  if (a == b) return;
  if (parents[a] < parents[b])
    parents[a] += parents[b], parents[b] = a;
  else
    parents[b] += parents[a], parents[a] = b;
}
void init() { memset(parents, (0xff), sizeof parents); }
int q[M];
bool ck[M];
int vis[M];
int n, m;
queue<int> que;
void upd(int t) {
  while (!que.empty()) que.pop();
  que.push(t);
  while (!que.empty()) {
    int x = que.front();
    que.pop();
    if (ck[x]) Union(t, ((1 << n) - 1) ^ x);
    if (vis[x] != -1) continue;
    vis[x] = t;
    for (int j = 0; j < (n); ++j)
      if ((x >> j & 1) == 0) {
        int u = x ^ (1 << j);
        que.push(u);
      }
  }
}
int main() {
  n = nextInt();
  m = nextInt();
  for (int i = 0; i < (m); ++i) q[i] = nextInt();
  init();
  int mask = (1 << n) - 1;
  memset(vis, (0xff), sizeof vis);
  for (int i = 0; i < (m); ++i) {
    int t = q[i];
    if (vis[mask ^ t] != -1) {
      Union(t, vis[mask ^ t]);
    }
    upd(t);
    ck[mask ^ t] = 1;
  }
  int ans = 0;
  for (int i = 0; i < (m); ++i)
    if (q[i] == Find(q[i])) ++ans;
  printf("%d\n", ans);
  return 0;
}
