#include <bits/stdc++.h>
using namespace std;
const int __BS = 4096;
static char __bur[__BS + 16], *__er = __bur + __BS, *__ir = __er;
template <class T = int>
T readInt() {
  auto c = [&]() {
    if (__ir >= __er)
      std::fill(__bur, __bur + __BS, 0), cin.read(__bur, __BS), __ir = __bur;
  };
  c();
  while (*__ir && (*__ir < '0' || *__ir > '9') && *__ir != '-') ++__ir;
  c();
  bool m = false;
  if (*__ir == '-') ++__ir, c(), m = true;
  T r = 0;
  while (*__ir >= '0' && *__ir <= '9') r = r * 10 + *__ir - '0', ++__ir, c();
  ++__ir;
  return m ? -r : r;
}
template <class T = double>
T readFloat() {
  auto c = [&]() {
    if (__ir >= __er)
      std::fill(__bur, __bur + __BS, 0), cin.read(__bur, __BS), __ir = __bur;
  };
  c();
  while (*__ir && (*__ir < '0' || *__ir > '9') && *__ir != '-') ++__ir;
  c();
  bool m = false;
  if (*__ir == '-') ++__ir, c(), m = true;
  T r = 0;
  while (*__ir >= '0' && *__ir <= '9') r = r * 10 + *__ir - '0', ++__ir, c();
  if (c(), *__ir == '.') {
    ++__ir;
    c();
    T t = 1;
    while (*__ir >= '0' && *__ir <= '9')
      t = t / 10, r += (*__ir - '0') * t, ++__ir, c();
  }
  ++__ir;
  return m ? -r : r;
}
static char __buw[__BS + 20], *__iw = __buw, *__ew = __buw + __BS;
template <class T>
void writeInt(T x, char endc = '\n') {
  if (x < 0) *__iw++ = '-', x = -x;
  if (x == 0) *__iw++ = '0';
  char* s = __iw;
  while (x) {
    T t = x / 10;
    char c = x - 10 * t + '0';
    *__iw++ = c;
    x = t;
  }
  char* f = __iw - 1;
  while (s < f) swap(*s, *f), ++s, --f;
  if (__iw > __ew) cout.write(__buw, __iw - __buw), __iw = __buw;
  if (endc) {
    *__iw++ = endc;
  }
}
template <class T>
void writeStr(const T& str) {
  int i = 0;
  while (str[i]) {
    *__iw++ = str[i++];
    if (__iw > __ew) cout.write(__buw, __iw - __buw), __iw = __buw;
  }
}
struct __FL__ {
  ~__FL__() {
    if (__iw != __buw) cout.write(__buw, __iw - __buw);
  }
};
static __FL__ __flushVar__;
const int maxn = 1 << 22;
int n, m, a[maxn], all;
bitset<maxn> vis, have;
void dfs(int x) {
  if (vis[x]) return;
  vis[x] = 1;
  if (have[x]) dfs(all ^ x);
  for (int i = 0; i < n; i++) {
    if (x & 1 << i) dfs(x ^ 1 << i);
  }
}
int main() {
  n = readInt<int>();
  m = readInt<int>();
  for (int i = 1; i <= m; i++) a[i] = readInt<int>();
  for (int i = 1; i <= m; i++) have[a[i]] = 1;
  all = 1 << n;
  all--;
  int res = 0;
  for (int i = 1; i <= m; i++) {
    if (!vis[a[i]]) {
      vis[a[i]] = 1;
      res++;
      dfs(all ^ a[i]);
    }
  }
  printf("%d\n", res);
  return 0;
}
