#include <bits/stdc++.h>
constexpr bool local = false;
using namespace std;
template <typename... Args>
void dbg(Args... args) {
  if (local) {
    fprintf(stderr, args...);
  }
}
int gInt() {
  int i;
  scanf("%d", &i);
  return i;
}
long long int gLong() {
  long long int i;
  scanf("%lld", &i);
  return i;
}
double gDouble() {
  double i;
  scanf("%lf", &i);
  return i;
}
void init() {}
void quit() {
  fclose(stdin);
  fclose(stdout);
  fclose(stderr);
  exit(0);
}
void body(int argc, char** argv);
int main(int argc, char** argv) {
  init();
  body(argc, argv);
  quit();
  return 0;
}
int n, m;
int mod;
int big;
vector<vector<int>> edges;
bool visited[1 << 23];
bool bfs(int node) {
  if (visited[node]) {
    return false;
  }
  visited[node] = true;
  queue<int> q;
  q.push(node);
  while (!q.empty()) {
    int next = q.front();
    q.pop();
    for (int neigh : edges[next]) {
      if (visited[neigh]) {
        continue;
      }
      visited[neigh] = true;
      q.push(neigh);
    }
    if (next >= mod) {
      int nid = next - mod;
      for (int c = 0; c < n; ++c) {
        int neigh = nid | (1 << c);
        if (neigh == nid) {
          continue;
        }
        neigh += mod;
        if (visited[neigh]) {
          continue;
        }
        visited[neigh] = true;
        q.push(neigh);
      }
    }
  }
  return true;
}
void body(int argc, char** argv) {
  n = gInt();
  m = gInt();
  mod = (1 << n);
  big = mod << 1;
  edges.resize(big);
  dbg("%d %d\n", mod, big);
  vector<int> ids;
  for (int i = 0; i < m; ++i) {
    int id = gInt();
    ids.push_back(id);
    edges[id].push_back(mod + id);
    edges[mod + (mod - id - 1)].push_back(id);
    dbg("edge 1 %d %d\n", id, mod + id);
    dbg("edge 2 %d %d\n", mod + mod - id - 1, id);
  }
  int ans = 0;
  for (int id : ids) {
    if (bfs(id)) {
      ++ans;
    }
  }
  printf("%d\n", ans);
}
