#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);
	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

vector <int> best[maxn];
const int C = 1;
const int D = 200;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1) f[i] = i;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]].pb(tab[i]);
	}

	sort(tab+1, tab+n+1);
	FOR(i, 1, min(D, n))
	{
		FOR(j, 1, n)
			if (i != j && ((tab[i] & tab[j]) == 0)) lacz(tab[i], tab[j]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				for (auto u : best[i ^ (1 << j)]) best[i].pb(u);
				sort(best[i].begin(), best[i].end());
				best[i].resize(distance(best[i].begin(), unique(best[i].begin(), best[i].end())));
				best[i].resize(min((int)best[i].size(), C));
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (!best[pp].empty())
		{
			for (auto u : best[pp])
			{
				lacz(u, tab[i]);
			}
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);

	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

int best[maxn][5];
const int C = 3;
const int D = 50;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1)
	{
		f[i] = i;
		FOR(j, 0, C-1) best[i][j] = inf;
	}

	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]][0] = tab[i];
	}

	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				int st = 0;
				FOR(kc, 0, C-1)
				{
					int xd = best[i ^ (1 << j)][kc];
					if (xd != inf)
					{
						while (st < C && best[i][st] < xd) ++st;
						if (best[i][st] == xd) continue;
						for (int iter = C - 1; iter > st; --iter) best[i][iter] = best[i][iter - 1];
						if (st < C) best[i][st] = xd;
					}
				}
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}

		FOR(iter, 0, C-1)
			if (best[pp][iter] != inf) lacz(best[pp][iter], tab[i]);
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);
	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

vector <int> best[maxn];
const int C = 4;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1) f[i] = i;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]].pb(tab[i]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				for (auto u : best[i ^ (1 << j)]) best[i].pb(u);
				sort(best[i].begin(), best[i].end());
				best[i].resize(distance(best[i].begin(), unique(best[i].begin(), best[i].end())));
				best[i].resize(min((int)best[i].size(), C));
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (!best[pp].empty())
		{
			for (auto u : best[pp])
			{
				lacz(u, tab[i]);
			}
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
vector <int> v[maxn];

void dfs(int x)
{
	odw[x] = 1;
	for (auto u : v[x])
		if (!odw[u]) dfs(u);
}

int best[maxn];
int main()
{
	boost;
	cin >> m >> n;
	FOR(i, 0, 1<<m) best[i] = inf;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]] = tab[i];
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) v[tab[i]].pb(tab[j]), v[tab[j]].pb(tab[i]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j)) best[i] = min(best[i], best[i ^ (1 << j)]);
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (best[pp] != inf)
		{
			v[best[pp]].pb(tab[i]);
			v[tab[i]].pb(best[pp]);
		}
	}

	int c = 0;
	FOR(i, 0, pot-1)
	{
		if (!jest[tab[i]]) continue;
		if (!odw[tab[i]])
		{
			++c;
			dfs(tab[i]);
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
vector <int> v[maxn];

void dfs(int x)
{
	odw[x] = 1;
	for (auto u : v[x])
		if (!odw[u]) dfs(u);
}

int best[maxn];
int main()
{
	boost;
	cin >> m >> n;
	FOR(i, 0, 1<<m) best[i] = inf;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]] = tab[i];
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) v[i].pb(j), v[j].pb(i);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j)) best[i] = min(best[i], best[i ^ (1 << j)]);
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (best[pp] != inf)
		{
			v[best[pp]].pb(tab[i]);
			v[tab[i]].pb(best[pp]);
		}
	}

	int c = 0;
	FOR(i, 0, pot-1)
	{
		if (!jest[tab[i]]) continue;
		if (!odw[tab[i]])
		{
			++c;
			dfs(tab[i]);
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);
	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

vector <int> best[maxn];
const int C = 1;
const int D = 20;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1) f[i] = i;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]].pb(tab[i]);
	}

	sort(tab+1, tab+n+1);
	FOR(i, 1, min(D, n))
	{
		FOR(j, 1, n)
			if (i != j && ((tab[i] & tab[j]) == 0)) lacz(tab[i], tab[j]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				for (auto u : best[i ^ (1 << j)]) best[i].pb(u);
				sort(best[i].begin(), best[i].end());
				best[i].resize(distance(best[i].begin(), unique(best[i].begin(), best[i].end())));
				best[i].resize(min((int)best[i].size(), C));
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (!best[pp].empty())
		{
			for (auto u : best[pp])
			{
				lacz(u, tab[i]);
			}
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);

	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

int best[maxn][5];
const int C = 5;
const int D = 50;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1)
	{
		f[i] = i;
		FOR(j, 0, C-1) best[i][j] = inf;
	}

	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]][0] = tab[i];
	}

	sort(tab+1, tab+n+1);
	FOR(i, 1, min(D, n))
	{
		FOR(j, 1, n)
			if (i != j && ((tab[i] & tab[j]) == 0)) lacz(tab[i], tab[j]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				int st = 0;
				FOR(kc, 0, C-1)
				{
					int xd = best[i ^ (1 << j)][kc];
					if (xd != inf)
					{
						while (st < C && best[i][st] < xd) ++st;
						if (best[i][st] == xd) continue;
						for (int iter = C - 1; iter > st; --iter) best[i][iter] = best[i][iter - 1];
						if (st < C) best[i][st] = xd;
					}
				}
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}

		FOR(iter, 0, C-1)
			if (best[pp][iter] != inf) lacz(best[pp][iter], tab[i]);
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);

	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

int best[maxn][5];
const int C = 2;
const int D = 50;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1)
	{
		f[i] = i;
		FOR(j, 0, C-1) best[i][j] = inf;
	}

	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]][0] = tab[i];
	}

	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				int st = 0;
				FOR(kc, 0, C-1)
				{
					int xd = best[i ^ (1 << j)][kc];
					if (xd != inf)
					{
						while (st < C && best[i][st] < xd) ++st;
						if (best[i][st] == xd) continue;
						for (int iter = C - 1; iter > st; --iter) best[i][iter] = best[i][iter - 1];
						if (st < C) best[i][st] = xd;
					}
				}
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}

		FOR(iter, 0, C-1)
			if (best[pp][iter] != inf) lacz(best[pp][iter], tab[i]);
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);
	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

vector <int> best[maxn];
const int C = 3;
const int D = 500;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1) f[i] = i;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]].pb(tab[i]);
	}

	sort(tab+1, tab+n+1);
	FOR(i, 1, min(D, n))
	{
		FOR(j, 1, n)
			if (i != j && ((tab[i] & tab[j]) == 0)) lacz(tab[i], tab[j]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				for (auto u : best[i ^ (1 << j)]) best[i].pb(u);
				sort(best[i].begin(), best[i].end());
				best[i].resize(distance(best[i].begin(), unique(best[i].begin(), best[i].end())));
				best[i].resize(min((int)best[i].size(), C));
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (!best[pp].empty())
		{
			for (auto u : best[pp])
			{
				lacz(u, tab[i]);
			}
		}
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);

	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

int best[maxn][5];
const int C = 5;
const int D = 50;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1)
	{
		f[i] = i;
		FOR(j, 0, C-1) best[i][j] = inf;
	}

	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]][0] = tab[i];
	}

	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				int st = 0;
				FOR(kc, 0, C-1)
				{
					int xd = best[i ^ (1 << j)][kc];
					if (xd != inf)
					{
						while (st < C && best[i][st] < xd) ++st;
						if (best[i][st] == xd) continue;
						for (int iter = C - 1; iter > st; --iter) best[i][iter] = best[i][iter - 1];
						if (st < C) best[i][st] = xd;
					}
				}
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}

		FOR(iter, 0, C-1)
			if (best[pp][iter] != inf) lacz(best[pp][iter], tab[i]);
	}

	cout << c << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost ios_base::sync_with_stdio(false)
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REYNA(i, a, b) for (int i=(a); i<(b); ++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PII, PII> PP;
typedef pair <PII, int> PPI;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const ll INF = 1e18;
const int mod = 1e9+7;
const int inf = 1e9+9;
const int maxn = (1 << 22);

int n, m;
bitset <maxn> odw, jest;
int tab[maxn];
int f[maxn];
inline int find(int a)
{
	if (f[a] == a) return a;
	f[a] = find(f[a]);
	return f[a];
}
int c;

void lacz(int a, int b)
{
	a = find(a); b = find(b);
	if (a == b) return;
	c--;
	if (a & 1) f[a] = b;
	else f[b] = a;
}

vector <int> best[maxn];
const int C = 3;
const int D = 50;

int main()
{
	boost;
	cin >> m >> n;
	c = n;
	FOR(i, 0, (1 << m)-1) f[i] = i;
	FOR(i, 1, n)
	{
		cin >> tab[i];
		jest[tab[i]] = 1;
		if (tab[i] == 0) OUT(1);
		best[tab[i]].pb(tab[i]);
	}

	sort(tab+1, tab+n+1);
	FOR(i, 1, min(D, n))
	{
		FOR(j, 1, n)
			if (i != j && ((tab[i] & tab[j]) == 0)) lacz(tab[i], tab[j]);
	}

	if (n <= 1000)
	{
		FOR(i, 1, n)
			FOR(j, i + 1, n)
				if ((tab[i] & tab[j]) == 0) lacz(tab[i], tab[j]);
	}
	int pot = (1 << m);
	FOR(i, 0, pot -1)
	{
		FOR(j, 0, m - 1)
			if (i & (1 << j))
			{
				for (auto u : best[i ^ (1 << j)]) best[i].pb(u);
				sort(best[i].begin(), best[i].end());
				best[i].resize(distance(best[i].begin(), unique(best[i].begin(), best[i].end())));
				best[i].resize(min((int)best[i].size(), C));
			}
	}

	FOR(i, 1, n)
	{
		int pp = 0;
		FOR(j, 0, m-1)
		{
			int bit = (tab[i] & (1 << j))?0:1;
			pp += bit * (1 << j);
		}
		if (!best[pp].empty())
		{
			for (auto u : best[pp])
			{
				lacz(u, tab[i]);
			}
		}
	}

	cout << c << endl;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 5;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 5;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn*2], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 5;
int dfn[maxn*2], low[maxn*2], stk[maxn];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 5;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22)+99;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 5;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bitset<maxn> f; bitset<maxn*2> bel;

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = (1 << 22) + 4;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;

const int maxn = 1 << 22;
int dfn[maxn*2], low[maxn*2], stk[maxn*2];
int N, n, m, res, top, ans, clk, x;
bool f[maxn], bel[maxn*2];

void tarjan(int u) {
    dfn[u] = low[u] = ++clk;
    stk[++top] = u;
    if (u < N) {
        if (f[u]) {
            int v = N + ((~u)&(N-1));
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (!bel[v]) low[u] = min(low[u], dfn[v]);
        }
    }
    else {
        int v; u -= N;
        rep (i, -1, n-1) if ((i == -1) || ((u>>i)&1)) {
            if (i == -1) v = u;
            else v = u - (1<<i) + N;
            if (!dfn[v]) tarjan(v), low[u+N] = min(low[u+N], low[v]);
            else if (!bel[v]) low[u+N] = min(low[u+N], dfn[v]);
        }
        u += N;
    }
    if (low[u] != dfn[u]) return;
    int flag = 0;
    while (stk[top] != u) {
        if (stk[top] < N) flag |= f[stk[top]];
        bel[stk[top--]] = 1;
    }
    if (stk[top] < N) flag |= f[stk[top]];
    bel[stk[top--]] = 1;
    res += flag;
}

int main() {
    scanf("%d%d", &n, &m);
    N = 1 << n;
    rep (i, 1, m) {
        scanf("%d", &x);
        f[x] = 1;
    }
    rep (i, 0, 2*N-1)
        if (!dfn[i]) tarjan(i);
    printf("%d\n", res);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define per(i,l,r) for (int i=l;i>=r;i--)
using namespace std;
const int maxn=8500000;
typedef long long ll;
int all,n,m,c,tot,vis[maxn],a[maxn],b[maxn];
/*struct edge{int obj,pre;}e[maxn*11];
void insert(int x,int y){
    e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot;
    //printf("%d %d\n",x,y);
}*/
void dfs(int u,int s){
    if (vis[u]) return;
//    printf("%d %d %d\n",c,u,s);
    vis[u]=1;
    if (u<all) {
        if (b[u]) dfs(u+all,s);
    }
    else {
        int x=u-all;
        rep(j,0,n-1) if (~(x>>j)&1) dfs(all+x+(1<<j),s);
        //if (b[all-x-1])
            dfs(all-x-1,s);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    rep(i,1,m) scanf("%d",&a[i]),b[a[i]]=1;
    all=(1<<n);
    rep(i,1,m) if (!vis[a[i]]) dfs(a[i],a[i]),c++;
    printf("%d\n",c);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define per(i,l,r) for (int i=l;i>=r;i--)
using namespace std;
const int maxn=8500000;
typedef long long ll;
int all,n,m,c,tot,vis[maxn],a[maxn],head[maxn];
struct edge{int obj,pre;}e[maxn*11];
void insert(int x,int y){
    e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot;
    //printf("%d %d\n",x,y);
}
void dfs(int u){
    vis[u]=1; //printf("sss%d %d\n",c,u);
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (!vis[v]) dfs(v);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    rep(i,1,m) scanf("%d",&a[i]);
    all=(1<<n)-1;
    rep(i,0,all){
        rep(j,0,n-1) if (~(i>>j)&1) insert(all+i,all+i+(1<<j));
        insert(all+i,all-i);
    }
    rep(i,1,m) insert(a[i],a[i]+all);
    rep(i,1,m) if (!vis[a[i]]) dfs(a[i]),c++;
    printf("%d\n",c);
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define per(i,l,r) for (int i=l;i>=r;i--)
using namespace std;
const int maxn=8500000;
typedef long long ll;
int all,n,m,c,tot,vis[maxn],a[maxn],b[maxn];
/*struct edge{int obj,pre;}e[maxn*11];
void insert(int x,int y){
    e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot;
    //printf("%d %d\n",x,y);
}*/
void dfs(int u,int s){
    if (vis[u]) return;
//    printf("%d %d %d\n",c,u,s);
    vis[u]=1;
    if (u<all&&b[u]) dfs(u+all,s);
    else {
        int x=u-all;
        rep(j,0,n-1) if (~(x>>j)&1) dfs(all+x+(1<<j),s);
        if (b[all-x-1]) dfs(all-x-1,s);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    rep(i,1,m) scanf("%d",&a[i]),b[a[i]]=1;
    all=(1<<n);
    rep(i,1,m) if (!vis[a[i]]) dfs(a[i],a[i]),c++;
    printf("%d\n",c);
    return 0;
}


/*input
5 5
5 19 10 20 12

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
// #define int ll
#define pb push_back
#define INF 1000000000
#define MOD 1000000007
#define mp make_pair
const double PI=3.141592653589793238462643383279502884197169399375105820974944;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
#define F first
#define S second
#define mii map<int,int>
#define vi vector<int>
#define vvi vector<vi>
#define itr :: iterator it
#define WL(t) while(t --)
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/gcd((a),(b))
#define print(arr) for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl;
#define debug(x) cout << x << endl;
#define debug2(x,y) cout << x << " " << y << endl;
#define debug3(x,y,z) cout << x << " " << y << " " << z << endl;

int power(int a,int b,int m = MOD){
	if(b == 0) return 1;
	if(b == 1) return a;
	int x = power(a,b/2,m)%m;
	x = (x*x)%m;
	if(b%2) return (x*a)%m;
	return x;
}

const int MX = (1<<22);

int n,m;
bitset<MX> a;
bitset<MX> vis[2];

void dfs(int i,int j){
	vis[i][j] = 1;
	if(i == 0){
		if(!vis[1][j]) dfs(1,j);
	}
	else{
		if(a[(1<<n)-1-j] and (!vis[0][(1<<n)-1-j])) dfs(0,(1<<n)-1-j);
		REP(k,n){
			if(!((1<<k)&j)){
				if(!vis[1][j|(1<<k)]) dfs(1,j|(1<<k));
			}
		}
	}
}

signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	REP(i,m){
		int x; cin >> x;
		a[x] = 1;
	}
	int ans = 0;
	REP(i,(1<<n)){
		if(a[i] and (!vis[0][i])){
			dfs(0,i);
			ans ++;
		}
	}
	cout << ans << endl;
}


/*input
5 5
5 19 10 20 12

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define int ll
#define pb push_back
#define INF 1000000000
#define MOD 1000000007
#define mp make_pair
const double PI=3.141592653589793238462643383279502884197169399375105820974944;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
#define F first
#define S second
#define mii map<int,int>
#define vi vector<int>
#define vvi vector<vi>
#define itr :: iterator it
#define WL(t) while(t --)
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/gcd((a),(b))
#define print(arr) for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl;
#define debug(x) cout << x << endl;
#define debug2(x,y) cout << x << " " << y << endl;
#define debug3(x,y,z) cout << x << " " << y << " " << z << endl;

int power(int a,int b,int m = MOD){
	if(b == 0) return 1;
	if(b == 1) return a;
	int x = power(a,b/2,m)%m;
	x = (x*x)%m;
	if(b%2) return (x*a)%m;
	return x;
}

const int MX = (1<<22);

int n,m;
bitset<MX> a;
vector<pii> adj[2][MX];
bitset<MX> vis[2];

void dfs(int i,int j){
	vis[i][j] = 1;
	for(auto x:adj[i][j]){
		if(!vis[x.F][x.S]) dfs(x.F,x.S);
	}
}

signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	REP(i,m){
		int x; cin >> x;
		a[x] = 1;
		adj[0][x].pb({1,x});
		adj[1][(1<<n)-1-x].pb({0,x});
	}
	REP(i,(1<<n)){
		int lol = i;
		REP(j,n){
			if(!((1<<j)&lol)){
				adj[1][lol].pb({1,lol|(1<<j)});
			}
		}
	}
	int ans = 0;
	REP(i,(1<<n)){
		if(a[i] and (!vis[0][i])){
			dfs(0,i);
			ans ++;
		}
	}
	cout << ans << endl;
}


/*input
5 5
5 19 10 20 12

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
// #define int ll
#define pb push_back
#define INF 1000000000
#define MOD 1000000007
#define mp make_pair
const double PI=3.141592653589793238462643383279502884197169399375105820974944;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
#define F first
#define S second
#define mii map<int,int>
#define vi vector<int>
#define vvi vector<vi>
#define itr :: iterator it
#define WL(t) while(t --)
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/gcd((a),(b))
#define print(arr) for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl;
#define debug(x) cout << x << endl;
#define debug2(x,y) cout << x << " " << y << endl;
#define debug3(x,y,z) cout << x << " " << y << " " << z << endl;

int power(int a,int b,int m = MOD){
	if(b == 0) return 1;
	if(b == 1) return a;
	int x = power(a,b/2,m)%m;
	x = (x*x)%m;
	if(b%2) return (x*a)%m;
	return x;
}

const int MX = (1<<22);

int n,m;
bitset<MX> a;
vector<pii> adj[2][MX];
bitset<MX> vis[2];

void dfs(int i,int j){
	vis[i][j] = 1;
	if(i == 0){
		if(!vis[1][j]) dfs(1,j);
	}
	else{
		if(a[(1<<n)-1-j] and (!vis[0][(1<<n)-1-j])) dfs(0,(1<<n)-1-j);
		REP(k,n){
			if(!((1<<k)&j)){
				if(!vis[1][j|(1<<k)]) dfs(1,j|(1<<k));
			}
		}
	}
}

signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	REP(i,m){
		int x; cin >> x;
		a[x] = 1;
	}
	REP(i,(1<<n)){
		int lol = i;
		REP(j,n){
			if(!((1<<j)&lol)){
				adj[1][lol].pb({1,lol|(1<<j)});
			}
		}
	}
	int ans = 0;
	REP(i,(1<<n)){
		if(a[i] and (!vis[0][i])){
			dfs(0,i);
			ans ++;
		}
	}
	cout << ans << endl;
}


/*input
5 5
5 19 10 20 12

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
// #define int ll
#define pb push_back
#define INF 1000000000
#define MOD 1000000007
#define mp make_pair
const double PI=3.141592653589793238462643383279502884197169399375105820974944;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
#define F first
#define S second
#define mii map<int,int>
#define vi vector<int>
#define vvi vector<vi>
#define itr :: iterator it
#define WL(t) while(t --)
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/gcd((a),(b))
#define print(arr) for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl;
#define debug(x) cout << x << endl;
#define debug2(x,y) cout << x << " " << y << endl;
#define debug3(x,y,z) cout << x << " " << y << " " << z << endl;

int power(int a,int b,int m = MOD){
	if(b == 0) return 1;
	if(b == 1) return a;
	int x = power(a,b/2,m)%m;
	x = (x*x)%m;
	if(b%2) return (x*a)%m;
	return x;
}

const int MX = (1<<22);

int n,m;
bitset<MX> a;
vector<pii> adj[2][MX];
bitset<MX> vis[2];

void dfs(int i,int j){
	vis[i][j] = 1;
	for(auto x:adj[i][j]){
		if(!vis[x.F][x.S]) dfs(x.F,x.S);
	}
}

signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	REP(i,m){
		int x; cin >> x;
		a[x] = 1;
		adj[0][x].pb({1,x});
		adj[1][(1<<n)-1-x].pb({0,x});
	}
	REP(i,(1<<n)){
		int lol = i;
		REP(j,n){
			if(!((1<<j)&lol)){
				adj[1][lol].pb({1,lol|(1<<j)});
			}
		}
	}
	int ans = 0;
	REP(i,(1<<n)){
		if(a[i] and (!vis[0][i])){
			dfs(0,i);
			ans ++;
		}
	}
	cout << ans << endl;
}


/*input
2 3
1 2 3

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define int ll
#define pb push_back
#define INF 1000000000
#define MOD 1000000007
#define mp make_pair
const double PI=3.141592653589793238462643383279502884197169399375105820974944;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
#define F first
#define S second
#define mii map<int,int>
#define vi vector<int>
#define vvi vector<vi>
#define itr :: iterator it
#define WL(t) while(t --)
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/gcd((a),(b))
#define print(arr) for (auto it = arr.begin(); it != arr.end(); ++it) cout << *it << " "; cout << endl;
#define debug(x) cout << x << endl;
#define debug2(x,y) cout << x << " " << y << endl;
#define debug3(x,y,z) cout << x << " " << y << " " << z << endl;

int power(int a,int b,int m = MOD){
	if(b == 0) return 1;
	if(b == 1) return a;
	int x = power(a,b/2,m)%m;
	x = (x*x)%m;
	if(b%2) return (x*a)%m;
	return x;
}

const int MX = (1<<22);

int n,m;
bitset<MX> a;
vector<pii> adj[2][MX];
bitset<MX> vis[2];

void dfs(int i,int j){
	vis[i][j] = 1;
	for(auto x:adj[i][j]){
		if(!vis[x.F][x.S]) dfs(x.F,x.S);
	}
}

signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	REP(i,m){
		int x; cin >> x;
		a[x] = 1;
		adj[0][x].pb({1,x});
		adj[1][(1<<n)-1-x].pb({0,x});
	}
	REP(i,(1<<n)){
		int lol = i;
		REP(j,n){
			if((1<<j)&lol){
				adj[1][lol].pb({0,lol|(1<<j)});
			}
		}
	}
	int ans = 0;
	REP(i,(1<<n)){
		if(a[i] and !vis[0][i]){
			dfs(0,i);
			ans ++;
		}
	}
	cout << ans << endl;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define int unsigned
#define maxn (1<<23)
using namespace std;
bool visit[maxn],exs[maxn];
int n,m;
int a[maxn],ans;
void dfs(int now) {
    if(visit[now])return;
    visit[now]=1;int ro=(~now)%(1<<n);
    if(exs[now])dfs(ro);
    for(int i=0;i<n;i++) {
        if((!((1<<i)&now)))continue;
        dfs((1<<i)^now);
    }
}
signed main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d",&a[i]);exs[a[i]]=1;}
    for(int i=1;i<=m;i++){if(visit[a[i]])continue;dfs(a[i]);ans++;}
    printf("%d",ans);//
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define int unsigned
#define maxn (1<<23)
using namespace std;
bool visit[maxn],exs[maxn];
int n,m;
int a[maxn],ans;
void dfs(int now) {
    if(visit[now])return;
    visit[now]=1;int ro=(~now)%(1<<n);
    if(exs[now])dfs(ro);
    for(int i=0;i<n;i++) {
        if((((1<<i)&now)))continue;
        dfs((1<<i)|now);
    }
}
signed main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d",&a[i]);exs[a[i]]=1;}
    for(int i=1;i<=m;i++){if(visit[a[i]])continue;dfs(a[i]);ans++;}
    printf("%d",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define int unsigned
#define maxn (1<<23)
using namespace std;
bool visit[maxn],exs[maxn];
int n,m;
int a[maxn],ans;
void dfs(int now) {
    if(visit[now])return;
    visit[now]=1;int ro=(~now)%(1<<n);
    if(exs[now])dfs(ro);
    for(int i=0;i<n;i++) {
        if((!((1<<i)&now)))continue;
        dfs((1<<i)^now);
    }
}
signed main() {//
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d",&a[i]);exs[a[i]]=1;}
    for(int i=1;i<=m;i++){if(visit[a[i]])continue;dfs(a[i]);ans++;}
    printf("%d",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define int unsigned
#define maxn (1<<23)
using namespace std;
bool visit[maxn],exs[maxn];
int n,m;
int a[maxn],ans;
void dfs(int now) {
    if(visit[now])return;
    visit[now]=1;int ro=(~now)%(1<<n);
    if(exs[now])dfs(ro);
    for(int i=0;i<n;i++) {
        if((!((1<<i)&now)))continue;
        dfs((1<<i)^now);
    }
}
signed main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d",&a[i]);exs[a[i]]=1;}
    for(int i=1;i<=m;i++){if(visit[a[i]])continue;dfs(a[i]);ans++;}
    printf("%d",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define int unsigned
#define maxn (1<<23)
using namespace std;
bool visit[maxn],exs[maxn];
int n,m;
int a[maxn],ans;
void dfs(int now) {
    if(visit[now])return;
    visit[now]=1;int ro=(~now)%(1<<n);
    if(exs[now])dfs(ro);
    for(int i=0;i<n;i++) {
        if((!((1<<i)&now)))continue;
        dfs((1<<i)^now);
    }
}
signed main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d",&a[i]);exs[a[i]]=1;}
    for(int i=1;i<=m;i++){if(visit[a[i]])continue;dfs(a[i]);ans++;}
    printf("%d",ans);/////
    return 0;
}


#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
	//and graph
	//http://codeforces.com/blog/entry/59758
	int connectedComponents(int n, vector<int>& nums) {
		int m = nums.size();
		int N = 1 << n;

		vector<vector<int>> graph(N << 1);

		for (auto num : nums) {
			graph[num + N].push_back(num);
		}

		for (auto num : nums) {
			for (int i = 0; i < n; ++i) {
				if ((num & 1 << i) == 0) {
					graph[num].push_back(num | 1 << i);
				}
			}
		}

		for (auto num : nums) {
			// graph[~num & (N - 1)].push_back(num + N);
			graph[N - 1 - num].push_back(num + N);
		}

		vector<bool> visited(N << 1, false);

		int res = 0;
		for (auto num : nums) {
			if (!visited[num + N]) {
				++res;
				// dfs(graph, num + N, visited);
				bfs(graph, num + N, visited);
			}
		}
		return res;
	}

private:
	void dfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		for (auto v : graph[u]) {
			if (!visited[v]) {
				dfs(graph, v, visited);
			}
		}
	}

	void bfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		queue<int> q;
		q.push(u);

		while (!q.empty()) {
			u = q.front();
			q.pop();

			for (auto v : graph[u]) {
				if (!visited[v]) {
					visited[v] = true;
					q.push(v);
				}
			}
		}
	}
};

int main(int argc, char** argv) {
	int n, m;
	scanf("%d%d", &n, &m);

	vector<int> nums;
	while (m-- > 0) {
		int num;
		scanf("%d", &num);
		nums.push_back(num);
	}

	Solution sol;

	printf("%d\n", sol.connectedComponents(n, nums));
}


#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
	//and graph
	//http://codeforces.com/blog/entry/59758
	int connectedComponents(int n, vector<int>& nums) {
		int m = nums.size();
		int N = 1 << n;

		vector<bool> visited(N << 1, false);

		//MLE if building the graph directly...
		// vector<vector<int>> graph(N << 1);

		// for (auto num : nums) {
		// 	graph[num + N].push_back(num);
		// }

		// for (int num = 0; num < N; ++num) {
		// 	for (int i = 0; i < n; ++i) {
		// 		if ((num & 1 << i) == 0) {
		// 			graph[num].push_back(num | 1 << i);
		// 		}
		// 	}
		// }

		// for (auto num : nums) {
		// 	graph[~num & (N - 1)].push_back(num + N);
		// 	// graph[N - 1 - num].push_back(num + N);
		// }

		q.resize(N << 1);
		bInNums.resize(N << 1);

		fill(bInNums.begin(), bInNums.end(), false);

		for (auto num : nums) {
			bInNums[num + N] = true;
		}

		int res = 0;
		for (auto num : nums) {
			if (!visited[num + N]) {
				++res;
				// dfs(graph, num + N, visited);
				// bfs(graph, num + N, visited);
				bfs2(visited, num + N, n);
			}
		}
		return res;
	}

private:
	void dfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		for (auto v : graph[u]) {
			if (!visited[v]) {
				dfs(graph, v, visited);
			}
		}
	}

	void bfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		queue<int> q;
		q.push(u);

		while (!q.empty()) {
			u = q.front();
			q.pop();

			for (auto v : graph[u]) {
				if (!visited[v]) {
					visited[v] = true;
					q.push(v);
				}
			}
		}
	}

	void bfs2(vector<bool>& visited, int u, int n) {
		int top = 0;
		q[top++] = u;
		int v = u;
		int N = 1 << n;
		for (int i = 0; i < top; ++i) {
			u = q[i];

			if (u >= N) {
				v = u - N;
				if (!visited[v]) {
					visited[v] = true;
					q[top++] = v;
				}
			} else {
				v = N - 1 - u + N;
				if (bInNums[v] && !visited[v]) {
					visited[v] = true;
					q[top++] = v;
				}

				for (int i = 0; i < n; ++i) {
					if ((u & 1 << i) == 0) {
						v = u | 1 << i;
						if (!visited[v]) {
							visited[v] = true;
							q[top++] = v;
						}
					}
				}
			}
		}
	}

	vector<int> q;
	vector<bool> bInNums;
};

int main(int argc, char** argv) {
	int n, m;
	scanf("%d%d", &n, &m);

	vector<int> nums;
	while (m-- > 0) {
		int num;
		scanf("%d", &num);
		nums.push_back(num);
	}

	Solution sol;

	printf("%d\n", sol.connectedComponents(n, nums));
}


#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
	//and graph
	//http://codeforces.com/blog/entry/59758
	int connectedComponents(int n, vector<int>& nums) {
		int m = nums.size();
		int N = 1 << n;

		vector<bool> visited(N << 1, false);

		//MLE if building the graph directly...
		// vector<vector<int>> graph(N << 1);

		// for (auto num : nums) {
		// 	graph[num + N].push_back(num);
		// }

		// for (int num = 0; num < N; ++num) {
		// 	for (int i = 0; i < n; ++i) {
		// 		if ((num & 1 << i) == 0) {
		// 			graph[num].push_back(num | 1 << i);
		// 		}
		// 	}
		// }

		// for (auto num : nums) {
		// 	graph[~num & (N - 1)].push_back(num + N);
		// 	// graph[N - 1 - num].push_back(num + N);
		// }

		q.resize(N << 1);
		bInNums.resize(N << 1);

		fill(bInNums.begin(), bInNums.end(), false);

		for (auto num : nums) {
			bInNums[num + N] = true;
		}

		int res = 0;
		for (auto num : nums) {
			if (!visited[num + N]) {
				++res;
				// dfs(graph, num + N, visited);
				// bfs(graph, num + N, visited);
				bfs2(visited, num + N, n);
			}
		}
		return res;
	}

private:
	void dfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		for (auto v : graph[u]) {
			if (!visited[v]) {
				dfs(graph, v, visited);
			}
		}
	}

	void bfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		queue<int> q;
		q.push(u);

		while (!q.empty()) {
			u = q.front();
			q.pop();

			for (auto v : graph[u]) {
				if (!visited[v]) {
					visited[v] = true;
					q.push(v);
				}
			}
		}
	}

	void bfs2(vector<bool>& visited, int u, int n) {
		int top = 0;
		q[top++] = u;
		int v = u;
		int N = 1 << n;
		visited[u] = true;
		for (int i = 0; i < top; ++i) {
			u = q[i];

			if (u >= N) {
				v = u - N;
				if (!visited[v]) {
					visited[v] = true;
					q[top++] = v;
				}
			} else {
				v = N - 1 - u + N;
				if (bInNums[v] && !visited[v]) {
					visited[v] = true;
					q[top++] = v;
				}

				for (int i = 0; i < n; ++i) {
					if ((u & 1 << i) == 0) {
						v = u | 1 << i;
						if (!visited[v]) {
							visited[v] = true;
							q[top++] = v;
						}
					}
				}
			}
		}
	}

	vector<int> q;
	vector<bool> bInNums;
};

int main(int argc, char** argv) {
	int n, m;
	scanf("%d%d", &n, &m);

	vector<int> nums;
	while (m-- > 0) {
		int num;
		scanf("%d", &num);
		nums.push_back(num);
	}

	Solution sol;

	printf("%d\n", sol.connectedComponents(n, nums));
}


#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
	//and graph
	//http://codeforces.com/blog/entry/59758
	int connectedComponents(int n, vector<int>& nums) {
		int m = nums.size();
		int N = 1 << n;

		vector<vector<int>> graph(N << 1);

		for (auto num : nums) {
			graph[num + N].push_back(num);
		}

		for (int num = 0; num < N; ++num) {
			for (int i = 0; i < n; ++i) {
				if ((num & 1 << i) == 0) {
					graph[num].push_back(num | 1 << i);
				}
			}
		}

		for (auto num : nums) {
			graph[~num & (N - 1)].push_back(num + N);
			// graph[N - 1 - num].push_back(num + N);
		}

		vector<bool> visited(N << 1, false);

		int res = 0;
		for (auto num : nums) {
			if (!visited[num + N]) {
				++res;
				dfs(graph, num + N, visited);
				// bfs(graph, num + N, visited);
			}
		}
		return res;
	}

private:
	void dfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		for (auto v : graph[u]) {
			if (!visited[v]) {
				dfs(graph, v, visited);
			}
		}
	}

	void bfs(vector<vector<int>>& graph, int u, vector<bool>& visited) {
		visited[u] = true;

		queue<int> q;
		q.push(u);

		while (!q.empty()) {
			u = q.front();
			q.pop();

			for (auto v : graph[u]) {
				if (!visited[v]) {
					visited[v] = true;
					q.push(v);
				}
			}
		}
	}
};

int main(int argc, char** argv) {
	int n, m;
	scanf("%d%d", &n, &m);

	vector<int> nums;
	while (m-- > 0) {
		int num;
		scanf("%d", &num);
		nums.push_back(num);
	}

	Solution sol;

	printf("%d\n", sol.connectedComponents(n, nums));
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    ok[now]=1;
    int t=now^tp,x=t;
    while(1){
        if(vis[x]&&!ok[x])dfs(x);
        if(!x)break;
        x=t&(x-1);
    }
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])dfs(A[i]),ans++;
    }
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    if(ok[now])return;
    ok[now]=1;
    if(vis[now])dfs(now^tp);
    int x=now,t=now-(x&-x);
    while(1){
        if(!ok[t])dfs(t);
        if(!x)break;
        t=now-(x&-x);
        x-=(x&-x);
    };
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++)if(!ok[A[i]])ok[A[i]]=1,dfs(A[i]^tp),ans++;
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    if(ok[now])return;
    ok[now]=1;
    if(vis[now])dfs(now^tp);
    int x=now,t=now-(x&-x);
    while(1){
        if(vis[t])dfs(t);
        if(!x)break;
        t=now-(x&-x);
        x-=x&-x;
    };
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])ok[A[i]]=1,dfs(A[i]^tp),ans++;
    }
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    ok[now]=1;
    int t=now^tp,x=t;
    while(1){
        if(vis[x]&&!ok[x])dfs(x);
        if(!x)break;
        x=t&(x-1);
    }
}
int main(){
    scanf("%d %d",&n,&m);
    if(!n){printf("0\n");return 0;}
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])dfs(A[i]),ans++;
    }
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    if(ok[now])return;
    ok[now]=1;
    if(vis[now])dfs(now^tp);
    int x=now,t=now;
    while(x){
        if(vis[t])dfs(t);
        x-=x&-x;
        t=now-(x&-x);
    }
  /*  for(int i=0;i<n;i++){
        if((1<<i)&now)dfs(now^(1<<i));
    }*/
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])ok[A[i]]=1,dfs(A[i]^tp),ans++;
    }
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    if(ok[now])return;
    ok[now]=1;
    if(vis[now])dfs(now^tp);
    int x=now,t=now;
    /*while(1){
        if(vis[t])dfs(t);
        t=now-(x&-x);
        x-=x&-x;
    }*/
    for(int i=0;i<n;i++){
        if((1<<i)&now)dfs(now^(1<<i));
    }
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])ok[A[i]]=1,dfs(A[i]^tp),ans++;
    }
    printf("%d\n",ans);
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int A[N],n,m,tp;
bool vis[N],ok[N];
void dfs(int now){
    if(ok[now])return;
    ok[now]=1;
    if(vis[now])dfs(now^tp);
    int x=now,t=now-(x&-x);
    while(x){
        if(vis[t])dfs(t);
        x-=x&-x;
        t=now-(x&-x);
    }
  /*  for(int i=0;i<n;i++){
        if((1<<i)&now)dfs(now^(1<<i));
    }*/
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)scanf("%d",&A[i]),vis[A[i]]=1;
    if(!n){printf("1\n");return 0;}
    tp=(1<<n)-1;
    int ans=0;
    for(int i=0;i<m;i++){
        if(!ok[A[i]])ok[A[i]]=1,dfs(A[i]^tp),ans++;
    }
    printf("%d\n",ans);
}


    #include <bits/stdc++.h>

                                            //    #include <boost/multiprecision/cpp_int.hpp>

                        //       	       #define int long long
                                                #define inf  1000000007
                                              #define pa pair<int,int>
                                               #define pad pair<double,double>
                                                #define ll long long
                                                #define pal pair<double,double>
                                                #define ppap pair<pa,int>
                                          #define PI 3.14159265358979323846
                                                #define paa pair<pa,pa>
                                                #define  mp make_pair
                                                #define  pb push_back
                                                #define EPS (1e-10)
                                                #define equals(a,b) (fabs((a)-(b))<EPS)
                                            //    #define double long double
        int dx[4]={0,-1,0,1};
        int dy[4]={1,0,-1,0};
                                                using namespace std;
                                       			class pa3{
                                                	public:
                                                	int x,y,z;
                                                	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                                	bool operator < (const pa3 &p) const{
                                                		if(x!=p.x) return x<p.x;
                                                		if(y!=p.y) return y<p.y;
                                                		 return z<p.z;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                       				bool operator > (const pa3 &p) const{
                                                		if(x!=p.x) return x>p.x;
                                                		if(y!=p.y) return y>p.y;
                                                		 return z>p.z;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const pa3 &p) const{
                                                		return x==p.x && y==p.y && z==p.z;
                                                	}
                                                		bool operator != (const pa3 &p) const{
                                                			return !( x==p.x && y==p.y && z==p.z);
                                                	}

                                                };

                                                class pa4{
                                                	public:
                                                	int x;
                                                	int y,z,w;
                                                	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                                	bool operator < (const pa4 &p) const{
                                                		if(x!=p.x) return x<p.x;
                                                		if(y!=p.y) return y<p.y;
                                                		if(z!=p.z)return z<p.z;
                                                		return w<p.w;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator > (const pa4 &p) const{
                                                		if(x!=p.x) return x>p.x;
                                                		if(y!=p.y) return y>p.y;
                                                		if(z!=p.z)return z>p.z;
                                                		return w>p.w;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const pa4 &p) const{
                                                		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                                	}

                                                	bool operator != (const pa4 &p) const{
                                                		return !(x==p.x && y==p.y && z==p.z &&w==p.w);
                                                	}

                                                };
                                                class pa2{
                                                	public:
                                                	int x,y;
                                                	pa2(int x=0,int y=0):x(x),y(y) {}
                                                	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                                	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                                	bool operator < (const pa2 &p) const{
                                                		return x!= p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator > (const pa2 &p) const{
                                                		return x != p.x ? x>p.x: y>p.y;
                                                	}
                                                	bool operator == (const pa2 &p) const{
                                                		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                                	}
                                                	bool operator != (const pa2 &p) const{
                                                		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                                	}

                                                };

                                                       #define ppa pair<int,pas>
                                                class Point{
                                                	public:
                                                	double x,y;
                                                	Point(double x=0,double y=0):x(x),y(y) {}
                                                	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
                                                	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
                                                	Point operator * (double a) {return Point(x*a,y*a);}
                                                	Point operator / (double a) {return Point(x/a,y/a);}
                                                	double absv() {return sqrt(norm());}
                                                	double norm() {return x*x+y*y;}
                                                	bool operator < (const Point &p) const{
                                                		return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const Point &p) const{
                                                		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
                                                	}
                                                };
                                                typedef Point Vector;
                                         #define pl pair<int,pas>
                                                struct Segment{
                                                Point p1,p2;
                                                };
                                                 double dot(Vector a,Vector b){
                                                	return a.x*b.x+a.y*b.y;
                                                }
                                                double cross(Vector a,Vector b){
                                                	return a.x*b.y-a.y*b.x;
                                                }

                    bool parareru(Point a,Point b,Point c,Point d){
                    //	if(abs(cross(a-b,d-c))<EPS)cout<<"dd "<<cross(a-b,d-c)<<endl;
                    	return abs(cross(a-b,d-c))<EPS;
                    }
                    double distance_ls_p(Point a, Point b, Point c) {
                      if ( dot(b-a, c-a) < EPS ) return (c-a).absv();
                      if ( dot(a-b, c-b) < EPS ) return (c-b).absv();
                      return abs(cross(b-a, c-a)) / (b-a).absv();
                    }
                    bool is_intersected_ls(Segment a,Segment b) {
                    	if(a.p1==b.p1||a.p2==b.p1||a.p1==b.p2||a.p2==b.p2) return false;
                    	if(parareru((a.p2),(a.p1),(a.p1),(b.p2))&&parareru((a.p2),(a.p1),(a.p1),(b.p1))){
                    //		cout<<"sss"<<endl;
                    		if(dot(a.p1-b.p1,a.p1-b.p2)<EPS) return true;
                    		if(dot(a.p2-b.p1,a.p2-b.p2)<EPS) return true;
                    		if(dot(a.p1-b.p1,a.p2-b.p1)<EPS) return true;
                    		if(dot(a.p1-b.p2,a.p2-b.p2)<EPS) return true;
                    		return false;
                    	}
                      else return ( cross(a.p2-a.p1, b.p1-a.p1) * cross(a.p2-a.p1, b.p2-a.p1) < EPS ) && ( cross(b.p2-b.p1, a.p1-b.p1) * cross(b.p2-b.p1, a.p2-b.p1) < EPS );
                    }

                    double segment_dis(Segment a,Segment b){
                    	if(is_intersected_ls(a,b))return 0;
                    	double r=distance_ls_p(a.p1, a.p2, b.p1);
                    	r=min(r,distance_ls_p(a.p1, a.p2, b.p2));
                    	r=min(r,distance_ls_p(b.p1, b.p2, a.p2));
                    	r=min(r,distance_ls_p(b.p1, b.p2, a.p1));
                    	return r;
                    }
                    Point intersection_ls(Segment a, Segment b) {
                      Point ba = b.p2-b.p1;
                      double d1 = abs(cross(ba, a.p1-b.p1));
                      double d2 = abs(cross(ba, a.p2-b.p1));
                      double t = d1 / (d1 + d2);

                      return a.p1 + (a.p2-a.p1) * t;
                    }

                                    string itos( int i ) {
                                    ostringstream s ;
                                    s << i ;
                                    return s.str() ;
                                    }

                                    int gcd(int v,int b){
                                    	if(v>b) return gcd(b,v);
                                    	if(v==b) return b;
                                    	if(b%v==0) return v;
                                    	return gcd(v,b%v);
                                    }

                                    double distans(double x1,double y1,double x2,double y2){
                                    	double rr=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                                    	return sqrt(rr);

                                    }
                                                        /*
        double bekid(double w,int r){
        	if(r==0) return 1.0;
        	if(r==1) return w;
        	if(r%2) return bekid(w,r-1)*w;
        	double f=bekid(w,r/2);
        	return f*f;
        }*/
                                    int mod;
                          /*
                    int pr[401000];
                    int inv[401000];

                    int beki(int wa,int rr,int warukazu){
                    	if(rr==0) return 1%warukazu;
                    	if(rr==1) return wa%warukazu;
                    	if(rr%2==1) return (beki(wa,rr-1,warukazu)*wa)%warukazu;
                    	int zx=beki(wa,rr/2,warukazu);
                    	return (zx*zx)%warukazu;
                    }

        			int comb(int nn,int rr){
        				int r=pr[nn]*inv[rr];
        				r%=mod;
        				r*=inv[nn-rr];
        				r%=mod;

        				return r;
        			}

                    void gya(int ert){
                    	pr[0]=1;
                    	for(int i=1;i<ert;i++){
                    		pr[i]=(pr[i-1]*i)%mod;
                    	}
                    	for(int i=0;i<ert;i++) inv[i]=beki(pr[i],mod-2,mod);

                    }
                    */

                  //   cin.tie(0);
        		//	ios::sync_with_stdio(false);
        			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;
                     //sort(ve.begin(),ve.end(),greater<int>());

                                          //----------------kokomade tenpure------------
bool a[1<<22]={0};
vector<int> ve;
bool sumi[1<<22]={0};
void dfs(int r){
	if(sumi[r]) return;
	sumi[r]=1;
	if(a[r]){
		ve.pb(r);
		a[r]=0;
	}
	for(int i=0;i<22;i++)if(r&(1<<i)){
		if(sumi[r^(1<<i)])continue;
		dfs(r^(1<<i));
	}
}
  signed main(){
  	              cin.tie(0);
    		ios::sync_with_stdio(false);
  	int f=(1<<22)-1;
  	int n,m;
  	cin>>n>>m;
  	for(int i=0;i<m;i++){
  		int y;
  		cin>>y;
  		a[y]=1;
  	}
  	int ans=0;
  	for(int i=0;i<(1<<22);i++)if(a[i]){
  		ans++;
  		a[i]=0;
  		ve.pb(i);
  	//	cout<<i<<endl;
  		while(ve.size()){
  			int g=ve.back();
  //			cout<<" "<<g<<endl;
  			ve.pop_back();
  			dfs(g^f);
  		}
  	}
  	cout<<ans<<endl;
  	return 0;
                }


    #include <bits/stdc++.h>

                                            //    #include <boost/multiprecision/cpp_int.hpp>

                               	       #define int long long
                                                #define inf  1000000007
                                              #define pa pair<int,int>
                                               #define pad pair<double,double>
                                                #define ll long long
                                                #define pal pair<double,double>
                                                #define ppap pair<pa,int>
                                          #define PI 3.14159265358979323846
                                                #define paa pair<pa,pa>
                                                #define  mp make_pair
                                                #define  pb push_back
                                                #define EPS (1e-10)
                                                #define equals(a,b) (fabs((a)-(b))<EPS)
                                            //    #define double long double
        int dx[4]={0,-1,0,1};
        int dy[4]={1,0,-1,0};
                                                using namespace std;
                                       			class pa3{
                                                	public:
                                                	int x,y,z;
                                                	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                                	bool operator < (const pa3 &p) const{
                                                		if(x!=p.x) return x<p.x;
                                                		if(y!=p.y) return y<p.y;
                                                		 return z<p.z;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                       				bool operator > (const pa3 &p) const{
                                                		if(x!=p.x) return x>p.x;
                                                		if(y!=p.y) return y>p.y;
                                                		 return z>p.z;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const pa3 &p) const{
                                                		return x==p.x && y==p.y && z==p.z;
                                                	}
                                                		bool operator != (const pa3 &p) const{
                                                			return !( x==p.x && y==p.y && z==p.z);
                                                	}

                                                };

                                                class pa4{
                                                	public:
                                                	int x;
                                                	int y,z,w;
                                                	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                                	bool operator < (const pa4 &p) const{
                                                		if(x!=p.x) return x<p.x;
                                                		if(y!=p.y) return y<p.y;
                                                		if(z!=p.z)return z<p.z;
                                                		return w<p.w;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator > (const pa4 &p) const{
                                                		if(x!=p.x) return x>p.x;
                                                		if(y!=p.y) return y>p.y;
                                                		if(z!=p.z)return z>p.z;
                                                		return w>p.w;
                                                		//return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const pa4 &p) const{
                                                		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                                	}

                                                	bool operator != (const pa4 &p) const{
                                                		return !(x==p.x && y==p.y && z==p.z &&w==p.w);
                                                	}

                                                };
                                                class pa2{
                                                	public:
                                                	int x,y;
                                                	pa2(int x=0,int y=0):x(x),y(y) {}
                                                	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                                	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                                	bool operator < (const pa2 &p) const{
                                                		return x!= p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator > (const pa2 &p) const{
                                                		return x != p.x ? x>p.x: y>p.y;
                                                	}
                                                	bool operator == (const pa2 &p) const{
                                                		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                                	}
                                                	bool operator != (const pa2 &p) const{
                                                		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                                	}

                                                };

                                                       #define ppa pair<int,pas>
                                                class Point{
                                                	public:
                                                	double x,y;
                                                	Point(double x=0,double y=0):x(x),y(y) {}
                                                	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
                                                	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
                                                	Point operator * (double a) {return Point(x*a,y*a);}
                                                	Point operator / (double a) {return Point(x/a,y/a);}
                                                	double absv() {return sqrt(norm());}
                                                	double norm() {return x*x+y*y;}
                                                	bool operator < (const Point &p) const{
                                                		return x != p.x ? x<p.x: y<p.y;
                                                	}
                                                	bool operator == (const Point &p) const{
                                                		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
                                                	}
                                                };
                                                typedef Point Vector;
                                         #define pl pair<int,pas>
                                                struct Segment{
                                                Point p1,p2;
                                                };
                                                 double dot(Vector a,Vector b){
                                                	return a.x*b.x+a.y*b.y;
                                                }
                                                double cross(Vector a,Vector b){
                                                	return a.x*b.y-a.y*b.x;
                                                }

                    bool parareru(Point a,Point b,Point c,Point d){
                    //	if(abs(cross(a-b,d-c))<EPS)cout<<"dd "<<cross(a-b,d-c)<<endl;
                    	return abs(cross(a-b,d-c))<EPS;
                    }
                    double distance_ls_p(Point a, Point b, Point c) {
                      if ( dot(b-a, c-a) < EPS ) return (c-a).absv();
                      if ( dot(a-b, c-b) < EPS ) return (c-b).absv();
                      return abs(cross(b-a, c-a)) / (b-a).absv();
                    }
                    bool is_intersected_ls(Segment a,Segment b) {
                    	if(a.p1==b.p1||a.p2==b.p1||a.p1==b.p2||a.p2==b.p2) return false;
                    	if(parareru((a.p2),(a.p1),(a.p1),(b.p2))&&parareru((a.p2),(a.p1),(a.p1),(b.p1))){
                    //		cout<<"sss"<<endl;
                    		if(dot(a.p1-b.p1,a.p1-b.p2)<EPS) return true;
                    		if(dot(a.p2-b.p1,a.p2-b.p2)<EPS) return true;
                    		if(dot(a.p1-b.p1,a.p2-b.p1)<EPS) return true;
                    		if(dot(a.p1-b.p2,a.p2-b.p2)<EPS) return true;
                    		return false;
                    	}
                      else return ( cross(a.p2-a.p1, b.p1-a.p1) * cross(a.p2-a.p1, b.p2-a.p1) < EPS ) && ( cross(b.p2-b.p1, a.p1-b.p1) * cross(b.p2-b.p1, a.p2-b.p1) < EPS );
                    }

                    double segment_dis(Segment a,Segment b){
                    	if(is_intersected_ls(a,b))return 0;
                    	double r=distance_ls_p(a.p1, a.p2, b.p1);
                    	r=min(r,distance_ls_p(a.p1, a.p2, b.p2));
                    	r=min(r,distance_ls_p(b.p1, b.p2, a.p2));
                    	r=min(r,distance_ls_p(b.p1, b.p2, a.p1));
                    	return r;
                    }
                    Point intersection_ls(Segment a, Segment b) {
                      Point ba = b.p2-b.p1;
                      double d1 = abs(cross(ba, a.p1-b.p1));
                      double d2 = abs(cross(ba, a.p2-b.p1));
                      double t = d1 / (d1 + d2);

                      return a.p1 + (a.p2-a.p1) * t;
                    }

                                    string itos( int i ) {
                                    ostringstream s ;
                                    s << i ;
                                    return s.str() ;
                                    }

                                    int gcd(int v,int b){
                                    	if(v>b) return gcd(b,v);
                                    	if(v==b) return b;
                                    	if(b%v==0) return v;
                                    	return gcd(v,b%v);
                                    }

                                    double distans(double x1,double y1,double x2,double y2){
                                    	double rr=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                                    	return sqrt(rr);

                                    }
                                                        /*
        double bekid(double w,int r){
        	if(r==0) return 1.0;
        	if(r==1) return w;
        	if(r%2) return bekid(w,r-1)*w;
        	double f=bekid(w,r/2);
        	return f*f;
        }*/
                                    int mod;
                          /*
                    int pr[401000];
                    int inv[401000];

                    int beki(int wa,int rr,int warukazu){
                    	if(rr==0) return 1%warukazu;
                    	if(rr==1) return wa%warukazu;
                    	if(rr%2==1) return (beki(wa,rr-1,warukazu)*wa)%warukazu;
                    	int zx=beki(wa,rr/2,warukazu);
                    	return (zx*zx)%warukazu;
                    }

        			int comb(int nn,int rr){
        				int r=pr[nn]*inv[rr];
        				r%=mod;
        				r*=inv[nn-rr];
        				r%=mod;

        				return r;
        			}

                    void gya(int ert){
                    	pr[0]=1;
                    	for(int i=1;i<ert;i++){
                    		pr[i]=(pr[i-1]*i)%mod;
                    	}
                    	for(int i=0;i<ert;i++) inv[i]=beki(pr[i],mod-2,mod);

                    }
                    */

                  //   cin.tie(0);
        		//	ios::sync_with_stdio(false);
        			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;
                     //sort(ve.begin(),ve.end(),greater<int>());

                                          //----------------kokomade tenpure------------
bool a[1<<22]={0};
vector<int> ve;
bool sumi[1<<22]={0};
void dfs(int r){
	if(sumi[r]) return;
	sumi[r]=1;
	if(a[r]){
		ve.pb(r);
		a[r]=0;
	}
	for(int i=0;i<22;i++)if(r&(1<<i)){
		if(sumi[r^(1<<i)])continue;
		dfs(r^(1<<i));
	}
}
  signed main(){
  	              cin.tie(0);
    		ios::sync_with_stdio(false);
  	int f=(1<<22)-1;
  	int n,m;
  	cin>>n>>m;
  	for(int i=0;i<m;i++){
  		int y;
  		cin>>y;
  		a[y]=1;
  	}
  	int ans=0;
  	for(int i=0;i<(1<<22);i++)if(a[i]){
  		ans++;
  		a[i]=0;
  		ve.pb(i);
  	//	cout<<i<<endl;
  		while(ve.size()){
  			int g=ve.back();
  //			cout<<" "<<g<<endl;
  			ve.pop_back();
  			dfs(g^f);
  		}
  	}
  	cout<<ans<<endl;
  	return 0;
                }