#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N=10100;
struct skt{
	long long t,kind;
}a[MAX_N];
bool cmp(skt a,skt b){
	return a.t<b.t;
}
int main(void){
	long long n,T,i,j;
	long long t,x,y;
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&t,&x,&y);
		long long num=0;
		long long st=0;
		for(i=1;i<=n;i++){
			scanf("%lld",&a[i].kind);
			if(!a[i].kind)
			num++;
		}
		for(i=1;i<=n;i++)
		scanf("%lld",&a[i].t);
		if(x*num+y*(n-num)<=t){
			printf("%lld\n",n);
			continue;
		}
		sort(a+1,a+n+1,cmp);
		long long ans=0;
		ans=min((a[0].t-1)/x,num);
		a[n+1].t=t+1;
		for(i=1;i<=n;i++){
			if(st>t)
			break;
			if(!a[i].kind){
				if(st+x<a[i+1].t){
					ans=max(ans,i);
				}
				num--;
				st+=x;
			}
			else{
				if(st+y<a[i+1].t){
					ans=max(ans,i);
				}
				else if(st<a[i].t){
					long long k=(a[i].t-1-st)/x;
					k=min(k,num);
					ans=max(ans,i-1+k);
				}
				st+=y;
			}
		}
		if(st<=t)
		ans=n;
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N=10100;
struct skt{
	long long t,kind;
}a[MAX_N];
bool cmp(skt a,skt b){
	return a.t<b.t;
}
int main(void){
	long long n,T,i,j,res;
	long long t,x,y;
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&t,&x,&y);
		long long num=0;
		long long st=0;
		for(i=1;i<=n;i++){
			scanf("%lld",&a[i].kind);
			if(!a[i].kind)
			num++;
		}
		for(i=1;i<=n;i++)
		scanf("%lld",&a[i].t);
		if(x*num+y*(n-num)<=t){
			printf("%lld\n",n);
			continue;
		}
		sort(a+1,a+n+1,cmp);
		long long ans=0;
		//cout<<a[1].t<<"！hi！！！\n";
		if(a[1].t)
		ans=min((a[1].t-1)/x,a[1].kind?num:num-1);
		a[n+1].t=t+1;
		for(i=1;i<=n;i++){
			res=0;
			if(!a[i].kind){
				num--;
				st+=x;
			}
			else
			st+=y;
			if(st<a[i+1].t){
				res=i;
				//cout<<res<<" hi\n";
				res+=min((a[i+1].t-1-st)/x,num);
			}
			//cout<<res<<" res\n";
			ans=max(ans,res);
			//cout<<ans<<"\n";
		}
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N=10100;
struct skt{
	long long t,kind;
}a[MAX_N];
bool cmp(skt a,skt b){
	return a.t<b.t;
}
int main(void){
	long long n,T,i,j;
	long long t,x,y;
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&t,&x,&y);
		long long num=0;
		long long st=0;
		for(i=1;i<=n;i++){
			scanf("%lld",&a[i].kind);
			if(!a[i].kind)
			num++;
		}
		for(i=1;i<=n;i++)
		scanf("%lld",&a[i].t);
		if(x*num+y*(n-num)<=t){
			printf("%lld\n",n);
			continue;
		}
		sort(a+1,a+n+1,cmp);
		long long ans=0;
		if(a[0].t)
		ans=min((a[0].t-1)/x,a[0].kind?num:num-1);
		a[n+1].t=t+1;
		for(i=1;i<=n;i++){
			if(st>t)
			break;
			if(!a[i].kind){
				if(st+x<a[i+1].t){
					ans=max(ans,i);
				}
				num--;
				st+=x;
			}
			else{
				if(st+y<a[i+1].t){
					ans=max(ans,i);
				}
				else if(st<a[i].t){
					long long k=(a[i].t-1-st)/x;
					k=min(k,num);
					ans=max(ans,i-1+k);
				}
				st+=y;
			}
		}
		if(st<=t)
		ans=n;
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N=10100;
struct skt{
	long long t,kind;
}a[MAX_N];
bool cmp(skt a,skt b){
	return a.t<b.t;
}
int main(void){
	long long n,T,i,j;
	long long t,x,y;
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld%lld",&n,&t,&x,&y);
		long long num=0;
		long long st=0;
		for(i=1;i<=n;i++){
			scanf("%lld",&a[i].kind);
			if(!a[i].kind)
			num++;
		}
		for(i=1;i<=n;i++)
		scanf("%lld",&a[i].t);
		sort(a+1,a+n+1,cmp);
		long long ans=0;
		a[n+1].t=t;
		for(i=1;i<=n;i++){
			if(st>t)
			break;
			if(!a[i].kind){
				if(st+x<a[i+1].t){
					ans=max(ans,i);
				}
				num--;
				st+=x;
			}
			else{
				if(st+y<a[i+1].t){
					ans=max(ans,i);
				}
				else if(st<a[i].t){
					long long k=(a[i].t-1-st)/x;
					k=min(k,num);
					ans=max(ans,i-1+k);
				}
				st+=y;
			}
		}
		if(st<=t)
		ans=n;
		printf("%lld\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct X
{
    ll t, bo;
};
X ara[200005];
bool func(X p, X q)
{
    if(p.t != q.t){
        return p.t < q.t;
    }
    return p.bo < q.bo;
}
int main()
{
    int T;
    cin>>T;

    while(T--){
        ll n, t, a, b;
        cin>>n>>t>>a>>b;
        map <ll, bool> m;

        ll totala = 0, totalb = 0;

        for(int i = 0; i < n; i++){
            cin>>ara[i].bo;
            (ara[i].bo == 1) ? totalb++ : totala++;
        }

        for(int i = 0; i < n; i++){
            cin>>ara[i].t;
        }
        sort(ara, ara+n, func);

        ll cnta = 0, cntb = 0, maxi = 0;

        ara[n].t = t+1;

        for(int i = 0; i <= n; i++){
            ll cost = (cnta*a) + (cntb*b);

            if(m[ara[i].t]){
                continue;
            }
            else{
                m[ara[i].t] = 1;
            }

            ll rmning = ara[i].t - cost;

            ll aroa = rmning/a;
            aroa = min(aroa, totala-cnta);
            rmning -= aroa*a;

            ll arob = rmning/b;
            arob = min(arob, totalb-cntb);
            rmning -= arob*b;

            if(cost < ara[i].t && maxi < (i+aroa+arob)){
                maxi = i+aroa+arob;
            }

            if(ara[i].bo){
                cntb++;
            }
            else{
                cnta++;
            }
        }
        cout<<maxi<<endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct X
{
    ll t, bo;
};
X ara[200005];
bool func(X p, X q)
{
    if(p.t != q.t){
        return p.t < q.t;
    }
    return p.bo < q.bo;
}
int main()
{
    int T;
    cin>>T;

    while(T--){
        ll n, t, a, b;
        cin>>n>>t>>a>>b;
        map <ll, bool> m;

        ll totala = 0, totalb = 0;

        for(int i = 0; i < n; i++){
            cin>>ara[i].bo;
            (ara[i].bo == 1) ? totalb++ : totala++;
        }

        for(int i = 0; i < n; i++){
            cin>>ara[i].t;
        }
        sort(ara, ara+n, func);

        ll cnta = 0, cntb = 0, maxi = 0;

        ara[n].t = t+1;

        for(int i = 0; i <= n; i++){
            ll cost = (cnta*a) + (cntb*b);

            if(m[ara[i].t]){
                continue;
            }
            else{
                m[ara[i].t] = 1;
            }

            ll rmning = ara[i].t - (cost+1);
            ll z = 0;
            rmning = max(z, rmning);

            ll aroa = rmning/a;
            aroa = min(aroa, totala-cnta);
            rmning -= (aroa*a);

            ll arob = rmning/b;
            arob = min(arob, totalb-cntb);
            rmning -= (arob*b);

            if(cost < ara[i].t && maxi < (i+aroa+arob)){
                maxi = i+aroa+arob;
            }

            if(ara[i].bo){
                cntb++;
            }
            else{
                cnta++;
            }
        }
        cout<<maxi<<endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct X
{
    ll t, bo;
};
X ara[200005];
bool func(X p, X q)
{
    if(p.t != q.t){
        return p.t < q.t;
    }
    return p.bo < q.bo;
}
int main()
{
    int T;
    cin>>T;

    while(T--){
        ll n, t, a, b;
        cin>>n>>t>>a>>b;
        map <ll, bool> m;

        ll totala = 0, totalb = 0;

        for(int i = 0; i < n; i++){
            cin>>ara[i].bo;
            (ara[i].bo == 1) ? totalb++ : totala++;
        }

        for(int i = 0; i < n; i++){
            cin>>ara[i].t;
        }
        sort(ara, ara+n, func);

        ll cnta = 0, cntb = 0, maxi = 0;

        ara[n].t = t+1;

        for(int i = 0; i <= n; i++){
            ll cost = (cnta*a) + (cntb*b);

            if(m[ara[i].t]){
                continue;
            }
            else{
                m[ara[i].t] = 1;
            }

            ll rmning = ara[i].t - cost;
            ll z = 0;
            rmning = max(z, rmning);

            ll aroa = rmning/a;
            aroa = min(aroa, totala-cnta);
            rmning -= aroa*a;

            ll arob = rmning/b;
            arob = min(arob, totalb-cntb);
            rmning -= arob*b;

            if(cost < ara[i].t && maxi < (i+aroa+arob)){
                maxi = i+aroa+arob;
            }

            if(ara[i].bo){
                cntb++;
            }
            else{
                cnta++;
            }
        }
        cout<<maxi<<endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct X
{
    ll t, bo;
};
X ara[200005];
bool func(X p, X q)
{
    if(p.t != q.t){
        return p.t < q.t;
    }
    return p.bo < q.bo;
}
int main()
{
    int T;
    cin>>T;

    while(T--){
        ll n, t, a, b;
        cin>>n>>t>>a>>b;
        map <ll, bool> m;

        ll totala = 0, totalb = 0;

        for(int i = 0; i < n; i++){
            cin>>ara[i].bo;
            (ara[i].bo == 1) ? totalb++ : totala++;
        }

        for(int i = 0; i < n; i++){
            cin>>ara[i].t;
        }
        sort(ara, ara+n, func);

        ll cnta = 0, cntb = 0, maxi = 0;

        ara[n].t = t+1;

        for(int i = 0; i <= n; i++){
            ll cost = (cnta*a) + (cntb*b);

            if(m[ara[i].t]){
                if(ara[i].bo){
                    cntb++;
                }
                else{
                    cnta++;
                }
                continue;
            }
            else{
                m[ara[i].t] = 1;
            }

            ll rmning = ara[i].t - (cost+1);
            ll z = 0;
            rmning = max(z, rmning);
            ll aroa = 0, arob = 0;

            if(rmning >= 0){
                aroa = rmning/a;
                aroa = min(aroa, totala-cnta);
                rmning -= (aroa*a);

                arob = rmning/b;
                arob = min(arob, totalb-cntb);
                rmning -= (arob*b);
            }

            if(cost < ara[i].t && maxi < (i+aroa+arob)){
                maxi = i+aroa+arob;
            }

            if(ara[i].bo){
                cntb++;
            }
            else{
                cnta++;
            }
        }
        cout<<maxi<<endl;
    }
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,1));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,(v[0].fi)-1/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
				cout<<i<<' '<<min((v[i+1].fi-now-1)/a,mud)<<endl;
				maxi=i+(min((v[i+1].fi-now-1)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		long long n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		long long mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,1));
		sort(v.begin(),v.end());
		long long now=0,maxi=min(mud,(max(0,v[0].fi-1))/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now-1)/a,mud)<<endl;
				maxi=max(maxi,i+min((v[i+1].fi-now-1)/a,mud)+1);
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,1));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,(max(0,v[0].fi-1))/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now-1)/a,mud)<<endl;
				maxi=max(maxi,i+(min((v[i+1].fi-now-1)/a,mud))+1);
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,0));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,v[0].fi/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
				maxi=i+(min((v[i+1].fi-now)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,1));
		sort(v.begin(),v.end());
		long long now=0,maxi=min(mud,(max(0,v[0].fi-1))/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now-1)/a,mud)<<endl;
				maxi=max(maxi,i+(min((v[i+1].fi-now-1)/a,mud))+1);
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m,1));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,v[0].fi/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now&&(i+1!=n||v[i+1].fi<now)){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now)/a,mud)<<endl;
				maxi=i+(min((v[i+1].fi-now)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m+1,1));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,(max(0,v[0].fi-1))/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now-1)/a,mud)<<endl;
				maxi=i+(min((v[i+1].fi-now-1)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m,1));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,(v[0].fi)-1/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now&&(i+1!=n||v[i+1].fi<now)){

			}else {
		//		cout<<i<<' '<<min((v[i+1].fi-now)/a,mud)<<endl;
				maxi=i+(min((v[i+1].fi-now-1)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


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

#define mp make_pair
#define fi first
#define se second

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	int t;
	cin>>t;
	while(t--){
		int n,m,a,b;
		cin>>n>>m>>a>>b;
		int c[n+1];
		vector<pair<int,int> >v;
		int mud=0;
		for(int i=1; i<=n; i++) cin>>c[i];
		for(int i=1; i<=n; i++){
			int x;
			cin>>x;
			v.push_back(mp(x,c[i]));
			if(c[i]==0) mud++;
		}
		v.push_back(mp(m,0));
		sort(v.begin(),v.end());
		int now=0,maxi=min(mud,v[0].fi/a);
		for(int i=0; i<v.size()-1; i++){
			if(v[i].se==1){
				now+=b;
			}else {
				now+=a;
				mud--;
			}
			if(v[i+1].fi<=now&&(i+1!=n||v[i+1].fi<now)){

			}else {
				maxi=i+(min((v[i+1].fi-now)/a,mud))+1;
			}
		}
		cout<<maxi<<endl;
	}
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	int M;
	int cnt = 0;
	cin >> m;
	M = m;
	while (m--) {
		cnt++;
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;

			if(cnt == 169 && M != 10) {
				cout << x << " ";
			}
		}
		if(cnt == 169 && M != 10)cout << "\n";
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			if(cnt == 169 && M != 10) {
				cout << tim << " ";
			}

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		if(cnt == 169 && M != 10) cout << "\n";
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;

							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		if(M == 10) cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		int totEasy = 0;
		int totHard = 0;
		int manEasy = 0;
		int manHard = 0;

		multiset<pair<ll, int>> events;

		for (int i = 0; i < n; i++) {
			cin >> hard[i];
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, int> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, -1));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		int totEasy = 0;
		int totHard = 0;
		int manEasy = 0;
		int manHard = 0;

		multiset<pair<ll, int>> events;

		for (int i = 0; i < n; i++) {
			cin >> hard[i];
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, int> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, -1));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	int M;
	int cnt = 0;
	cin >> m;
	M = m;
	while (m--) {
		cnt++;
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;
		/*
		if(cnt == 169 && M != 10) {
			cout << n << " " << T << " " << a << " " << b << "\n";
		}
		*/
		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;

			//if(cnt == 169 && M != 10) {
		//		cout << x << " ";
			//}
		}
		//if(cnt == 169 && M != 10)cout << "\n";
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

		//	if(cnt == 169 && M != 10) {
		//		cout << tim << " ";
		//	}

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		//if(cnt == 169 && M != 10) cout << "\n";
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp >= 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp >= 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp >= 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;

							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template <class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	int M;
	int cnt = 0;
	cin >> m;
	M = m;
	while (m--) {
		cnt++;
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		if(cnt == 169 && M != 10) {
			cout << n << " " << T << " " << a << " " << b << "\n";
		}

		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;

			if(cnt == 169 && M != 10) {
				cout << x << " ";
			}
		}
		if(cnt == 169 && M != 10)cout << "\n";
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			if(cnt == 169 && M != 10) {
				cout << tim << " ";
			}

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		if(cnt == 169 && M != 10) cout << "\n";
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;

							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		if(M == 10) cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	int M;
	int cnt = 0;
	cin >> m;
	M = m;
	while (m--) {
		cnt++;
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;
		/*
		if(cnt == 169 && M != 10) {
			cout << n << " " << T << " " << a << " " << b << "\n";
		}
		*/
		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;

			//if(cnt == 169 && M != 10) {
		//		cout << x << " ";
			//}
		}
		//if(cnt == 169 && M != 10)cout << "\n";
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

		//	if(cnt == 169 && M != 10) {
		//		cout << tim << " ";
		//	}

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		//if(cnt == 169 && M != 10) cout << "\n";
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp >= 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp >= 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp >= 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;

							}
						}
					}

				}

				ans = max(ans, num);

				cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		multiset<pair<ll, ll>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, ll> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, LLONG_MAX));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim ;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		int totEasy = 0;
		int totHard = 0;
		int manEasy = 0;
		int manHard = 0;

		multiset<pair<ll, int>> events;

		for (int i = 0; i < n; i++) {
			cin >> hard[i];
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, int> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, -1));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC optimize("O3")
#pragma GCC target("sse4")

using namespace std;

template<class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class T> //CANNOT ERASE FROM ORDERED MULTISET!!
using ordered_multiset = __gnu_pbds::tree<T, __gnu_pbds::null_type, less_equal<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template<class K, class T>
using hash_map = __gnu_pbds::gp_hash_table<K,T>;
template<class K, class T, class L>
using hash_map_custom_hash = __gnu_pbds::gp_hash_table<K,T,L>;

typedef long long ll;

#define IN_PROGRESS 1
#if IN_PROGRESS > 0

bool hard[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int m;
	cin >> m;
	while (m--) {
		int n;
		ll T;
		ll a, b;
		cin >> n >> T >> a >> b;

		ll totEasy = 0;
		ll totHard = 0;
		ll manEasy = 0;
		ll manHard = 0;

		multiset<pair<ll, int>> events;

		for (int i = 0; i < n; i++) {
			int x; cin >> x;
			if(x == 1) hard[i] = 1;
			else hard[i] = 0;
			if (hard[i]) totHard++;
			else totEasy++;
		}
		for (int i = 0; i < n; i++) {
			ll tim;
			cin >> tim;

			pair<ll, int> event = make_pair(tim, hard[i]);
			events.insert(event);
		}
		events.insert(make_pair(T + 1, 100));

		ll ans = 0;

		while (!events.empty()) {
			ll tim = events.begin()->first - 1;
			if(tim > T) break;
			if (tim >= 0) {
				ll temp = tim;
				ll num = 0;
				num += min(temp / a, (ll) manEasy);
				temp -= manEasy * a;
				if(num < manEasy) num = 0;
				else if (temp > 0) {
					num += min(temp / b, (ll) manHard);
					temp -= manHard * b;

					if (num < manEasy + manHard) num = 0;
					else {
						if (temp > 0) {
							num += min(temp / a, (ll) totEasy);
							temp -= totEasy * a;

							if (temp > 0) {
								num += min(temp / b, (ll) totHard);
								temp -= totHard * b;
							}
						}
					}

				}

				ans = max(ans, num);

			//	cout << tim << " " << num << " " << manEasy << " " << manHard << " " << totEasy << " " << totHard << "\n";
			}

			ll removeTim = tim + 1;
			while (!events.empty() && events.begin()->first == removeTim) {
				auto a = *events.begin();
				if (a.second == 1) {
					totHard--;
					manHard++;
				}
				if (a.second == 0) {
					totEasy--;
					manEasy++;
				}
				events.erase(events.begin());
			}
		}

		cout << ans << "\n";

	}

	return 0;
}
#endif


#include<bits/stdc++.h>
using namespace std;
const int N = 1<<22;
int used[N];
int present[N];
int n, m;
int msk;
void bfs(int x){
	queue<int> q;
	q.push(x);
	while(!q.empty()){
		int c = q.front();
		//cout << c << endl;
		int ccmp = msk - c;
		if(present[ccmp] && used[ccmp] == 0){
			q.push(ccmp);
			used[ccmp] = 1;
		}
		used[c] = 1;
		q.pop();
		for(int i=0; i<n; i++){
			int mc = 1 << i;
			if((c&mc) == 0){
				int nmc = c | mc;
				if(used[nmc] == 0){
					q.push(nmc);
					used[nmc] = 1;
				}
			}
		}
	}
}

int main(){

	cin >> n >> m;
	vector<int> a(m);
	msk = (1<<n) - 1;
	for(int i=0; i<m; i++) {
		cin >> a[i];
		present[a[i]] = 1;
	}
	int ans = 0;
	//bfs(a[0]);
	for(int i=0; i<m; i++){
		int ccmp = msk - a[i];
		if(used[ccmp] == 0) ans++;
		if(used[a[i]] == 0){
			bfs(a[i]);
			//cout << "A: " << a[i] << endl;
		}
	}
	cout << ans << '\n';
}


#include <bits/stdc++.h>
// dp[i][j] mean we are in the subtree of i and at state j ( j==0 means i in array , else i not in array )
// We can see i & ~i == 0 ( ~i = ( i ^ (1<<i - 1) ) )
// 1 & 0 == 0
// 0 & 0 == 0
// 0 & 1 == 0
// we call k will be the number that i & k == 0
// at bit j == 0 in i we have two choices : bit j in k = 0 || = 1
// at bit j == 1 in i we only have one choice : bit j in k = 0

using namespace std;
int dp[(1<<22)][2],a[(1<<22)];
int n,m;

void DFS(int u,int type)
{
	if(dp[u][type])
		return;
	dp[u][type] = true;

	if(!type)
		DFS(u,1);
	else
	{
		for(int i=0;i<n;i++)
		{
			if(((u>>i)&1)==0)
				DFS(u^(1<<i),1);
		}
		DFS(u^((1<<n)-1),0);
	}
}

signed main()
{
	cin>>n>>m;

	for(int i=0;i<m;i++)
		cin>>a[i];

	for(int i=0;i<(1<<n);i++)
		dp[i][0] = true;

	for(int i=0;i<m;i++)
		dp[a[i]][0] = false;

	int ans = 0;
	for(int i=0;i<m;i++)
	{
		if(!dp[a[i]][0])
		{
			ans++;
			DFS(a[i],0);
		}
	}

	cout<<ans;
}


#include <bits/stdc++.h>
// dp[i][j] mean we are in the subtree of i and at state j ( j==0 means i in array , else i not in array )
// We can see i & ~i == 0 ( ~i = ( i ^ (1<<i - 1) ) )
// 1 & 0 == 0
// 0 & 0 == 0
// 0 & 1 == 0
// we call k will be the number that i & k == 0
// at bit j == 0 in i we have two choices : bit j in k = 0 || = 1
// at bit j == 1 in i we only have one choice : bit j in k = 0

using namespace std;
int dp[(1<<22)][2],a[(1<<22)];
int n,m;

void DFS(int u,int type)
{
	if(dp[u][type])
		return;
	dp[u][type] = true;

	if(!type)
		DFS(u,1);
	else
	{
		for(int i=0;i<n;i++)
		{
			if(((u>>i)&1)==0)
				DFS(u^(1<<i),1);
		}
		DFS(u^((1<<n)-1),0);
	}
}

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

	cin>>n>>m;
	for(int i=0;i<(1<<n);i++)
		dp[i][0] = true;

	for(int i=0;i<m;i++)
	{
		cin>>a[i];
		dp[a[i]][0] = false;
	}

	int ans = 0;
	for(int i=0;i<m;i++)
	{
		if(!dp[a[i]][0])
		{
			ans++;
			DFS(a[i],0);
		}
	}

	cout<<ans;
}


#include <bits/stdc++.h>
#define bw(i,r,l) for (int i=r-1;i>=l;i--)
#define fw(i,l,r) for (int i=l;i<r;i++)
using namespace std;
int n,m,a[1<<22],ans=0; bool vis[1<<22][2];
void dfs(int u,bool state) {
	if (vis[u][state]) return;
	vis[u][state]=true;
	//if (!state) dfs(u,1);
	//else {
		fw (i,0,n) if (!(u&(1<<i))) dfs(u|(1<<i),0);
		dfs(u^((1<<n)-1),0);
	//}
}
signed main() {
	//freopen("986.inp","r",stdin);
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin>>n>>m; memset(vis,false,sizeof(vis));
	fw (i,0,(1<<n)) vis[i][0]=true;
	fw (i,0,m) {cin>>a[i]; vis[a[i]][0]=false;}
	fw (i,0,m) if (!vis[a[i]][0]) {
		ans++; dfs(a[i],0);
	}
	cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
int vis[maxn];
int a[maxn];
int n,m;

void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=1;
    x=(1<<n)-1-x;
    for(int i=0;i<=n;i++)
    {
        if(x&(1<<i))
            dfs(x^(1<<i));
    }
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int add;
        cin>>add;
        a[add]=1;
    }
    int ans=0;
    for(int i=0;i<(1<<n);i++)
    {
        if(a[i]&&!vis[i])
        {
            dfs(i);
            ans++;
        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
int c[23];
int vis[maxn];
int a[maxn],cont[maxn];
int n,m;

void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=1;
    if(a[x])
        dfs(x^(c[n]-1));
    for(int i=0;i<=n;i++)
    {
        if(x&c[i])
            dfs(x^c[i]);
    }
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    c[0]=1;
    for(int i=1;i<=22;i++)
    {
        c[i]=c[i-1]<<1;
    }
    for(int i=0;i<m;i++)
    {
        cin>>cont[i];
        a[cont[i]]=1;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        if(!vis[cont[i]])
        {
            ans++;
            dfs(cont[i]^(a[n]-1));
        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
bool vis[maxn];
bool a[maxn];
int n,m;
void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=true;
    for(int i=0;i<=n;i++)
    {
        if(x&(1<<i))
        dfs(x^(1<<i));
    }
    if(a[x])
        dfs((1<<n)-1-x);
}
int main()
{
    scanf("%d %d",&n,&m);
    int x;
    for(int i=0;i<m;i++)
    {
        cin>>x;
        a[x]=true;
    }
    int ans=0;
    for(int i=0;i<(1<<n);i++)
    {
        if(!vis[i]&&a[i])
        {
            dfs(i);
            ans++;
        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
bool vis[maxn];
bool a[maxn];
int n,m;
void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=true;
    for(int i=0;i<=n;i++)
    {
        if(x&(1<<i))
        dfs(x^(1<<i));
    }
    if(a[x])
        dfs((1<<n)-1-x);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    int x;
    for(int i=0;i<m;i++)
    {
        cin>>x;
        a[x]=true;
    }
    int ans=0;
    for(int i=0;i<(1<<n);i++)
    {
        if(!vis[i]&&a[i])
        {
            dfs(i);
            ans++;
        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
int c[23];
int vis[maxn];
int a[maxn],cont[maxn];
int n,m;

void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=1;
    if(a[x])
        dfs(x^(c[n]-1));
    for(int i=0;i<=n;i++)
    {
        if(x&c[i])
            dfs(x^c[i]);
    }
}
int main()
{
    //ios_base::sync_with_stdio(0);
    //cin.tie(0);
    cin>>n>>m;
    c[0]=1;
    for(int i=1;i<=22;i++)
    {
        c[i]=c[i-1]<<1;
    }
    for(int i=0;i<m;i++)
    {
        cin>>cont[i];
        a[cont[i]]=1;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        if(!vis[cont[i]])
        {
            ans++;
            vis[cont[i]]=1;
            dfs(cont[i]^(c[n]-1));
        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<23;
int c[23];
int vis[maxn];
int a[maxn],cont[maxn];
int n,m;

void dfs(int x)
{
    if(vis[x])
        return;
    vis[x]=1;
    if(a[x])
        dfs(x^(c[n]-1));
    for(int i=0;i<=n;i++)
    {
        if(x&c[i])
            dfs(x^c[i]);
    }
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    c[0]=1;
    for(int i=1;i<=22;i++)
    {
        c[i]=c[i-1]<<1;
    }
    for(int i=0;i<m;i++)
    {
        cin>>cont[i];
        a[cont[i]]=1;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        if(!vis[cont[i]])
        {
            ans++;
            vis[cont[i]]=1;
            dfs(cont[i]^(c[n]-1));
        }
    }
    cout<<ans<<endl;
}


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

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()
#define dump(x) cout << #x << " = " << (x) << endl
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os<<"{";
	rep(i, v.size()) {
		if (i) os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

const int maxn = 1 << 22;

int n, m;
int a[maxn];
vi g[maxn * 2];
bool vis[maxn * 2];

void dfs(int v) {
	vis[v] = true;
	for (int to : g[v]) {
		if (!vis[to]) {
			dfs(to);
		}
	}

	if (v < (1<<n)) {
		rep(i, n) {
			if ((v>>i)&1) {
				int nx = v ^ (1 << i);
				if (!vis[nx]) dfs(nx);
			}
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);

	rep(i, m) {
		scanf("%d", &a[i]);
	}

	rep(i, m) {
		g[(1<<n)+i].pb((1<<n)-1-a[i]);
		g[a[i]].pb((1<<n)+i);
	}

	int now = 0;
	rep(i, m) {
		if (!vis[(1<<n)+i]) {
			dfs((1<<n)+i);
			now++;
		}
	}

	cout << now << endl;

	return 0;
}


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

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()
#define dump(x) cout << #x << " = " << (x) << endl
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os<<"{";
	rep(i, v.size()) {
		if (i) os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

const int maxn = 1 << 22;

int a[maxn];
vi g[maxn * 2];
bool vis[maxn * 2];

void dfs(int v) {
	vis[v] = true;
	for (int to : g[v]) {
		if (!vis[to]) {
			dfs(to);
		}
	}
}

int main() {
	int n, m; scanf("%d %d", &n, &m);

	rep(i, m) {
		scanf("%d", &a[i]);
	}

	rep(i, n) {
		rep(j, 1 << n) {
			if (((j >> i) & 1) == 0) {
				g[j | (1 << i)].pb(j);
			}
		}
	}

	rep(i, m) {
		g[(1<<n)+i].pb((1<<n)-1-a[i]);
		g[a[i]].pb((1<<n)+i);
	}

	int now = 0;
	rep(i, m) {
		if (!vis[(1<<n)+i]) {
			dfs((1<<n)+i);
			now++;
		}
	}

	cout << now << endl;

	return 0;
}


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

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()
#define dump(x) cout << #x << " = " << (x) << endl
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os<<"{";
	rep(i, v.size()) {
		if (i) os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

const int maxn = 1 << 22;

int n, m;
int a[maxn];
bool vis[maxn * 2];
vi vec[maxn];

void dfs(int v) {
	vis[v] = true;

	if (v < (1<<n)) {
		rep(i, n) {
			if ((v >> i) & 1) {
				int nx = v ^ (1 << i);
				if (!vis[nx]) dfs(nx);
			}
		}
		for (int id : vec[v]) {
			if (!vis[(1<<n)+id]) {
				dfs((1<<n)+id);
			}
		}

	} else {
		int id = v - (1<<n);
		if (!vis[(1<<n)-1-a[id]]) {
			dfs((1<<n)-1-a[id]);
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);

	rep(i, m) {
		scanf("%d", &a[i]);
		vec[a[i]].pb(i);
	}

	int now = 0;
	rep(i, m) {
		if (!vis[(1<<n)+i]) {
			dfs((1<<n)+i);
			now++;
		}
	}

	cout << now << endl;

	return 0;
}


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

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()
#define dump(x) cout << #x << " = " << (x) << endl
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os<<"{";
	rep(i, v.size()) {
		if (i) os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

const int maxn = 1 << 22;

int n, m;
int a[maxn];
vector<short> g[maxn * 2];
bool vis[maxn * 2];

void dfs(int v) {
	vis[v] = true;
	for (int to : g[v]) {
		if (!vis[to]) {
			dfs(to);
		}
	}

	if (v < (1<<n)) {
		rep(i, n) {
			if ((v>>i)&1) {
				int nx = v ^ (1 << i);
				if (!vis[nx]) dfs(nx);
			}
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);

	rep(i, m) {
		scanf("%d", &a[i]);
	}

	rep(i, m) {
		g[(1<<n)+i].pb((1<<n)-1-a[i]);
		g[a[i]].pb((1<<n)+i);
	}

	int now = 0;
	rep(i, m) {
		if (!vis[(1<<n)+i]) {
			dfs((1<<n)+i);
			now++;
		}
	}

	cout << now << endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<cstdlib>
#include<complex>
#include<list>
#include<cassert>
#include<iomanip>
#include<limits>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;
typedef vector<int> vi;
long long mod = 1000000009LL;
long long large = 2000000000000000000LL;

int n,m;
vector<int> cnt;
int sz;

vector<int> dfs_num,dfs_low,S,visited;
vector<vector<int> > adj;
vector<vector<int> > Scc;
int dfsNumberCounter = 0, numSCC = 0;
void tarjanSCC(int u){
	dfs_low[u]=dfs_num[u]=dfsNumberCounter++;
	S.push_back(u);
	visited[u]=1;
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j];
		if(dfs_num[v]==-1){
			tarjanSCC(v);
		}
		if(visited[v]==1){
			dfs_low[u]=min(dfs_low[u],dfs_low[v]);
		}
	}
	for(int j=0;j<n;j++){
		if(u&(1<<j)){
			int v = u^(1<<j);
			if(dfs_num[v]==-1){
				tarjanSCC(v);
			}
			if(visited[v]==1){
				dfs_low[u]=min(dfs_low[u],dfs_low[v]);
			}
		}
	}

	if(dfs_low[u]==dfs_num[u]){
		Scc.push_back(vector<int>(0,0));
		while(true){
			int v= S.back();
			S.pop_back();
			visited[v]=0;
			Scc[numSCC].push_back(v);
			if(u==v) break;
		}
		numSCC++;
	}
}

int main(){

	cin>>n>>m;
	sz  = (1<<n);
	cnt.assign(1<<n,0);
	for(int i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}
	adj.assign(sz,vector<int>());
	for(int i=0;i<sz;i++){
		for(int j=0;j<n;j++){
			if(i&(1<<j)){
				int v = i^(1<<j);
				adj[i].push_back(v);
			}
		}
	}

	dfs_num.assign(sz,-1);
	dfs_low.assign(sz,0);
	visited.assign(sz,0);
	for(int i=0;i<sz;i++){
		if(dfs_num[i]==-1){
			tarjanSCC(i);
		}
	}

	int cc = 0;
	for(int i=0;i<(int)Scc.size();i++){
		bool flag = false;
		for(int j=0;j<(int)Scc[i].size();j++){
			//cout<<Scc[i][j]<<" ";
			if(cnt[Scc[i][j]]) flag = true;
		}
		//cout<<endl;
		if(flag) cc++;
	}
	cout<<cc<<endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<cstdlib>
#include<complex>
#include<list>
#include<cassert>
#include<iomanip>
#include<limits>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;
typedef vector<int> vi;
long long mod = 1000000009LL;
long long large = 2000000000000000000LL;

int n,m;
vector<int> cnt;
int sz;

vector<int> dfs_num,dfs_low,S,visited;
vector<vector<int> > Scc;
int dfsNumberCounter = 0, numSCC = 0;
void tarjanSCC(int u){
	dfs_low[u]=dfs_num[u]=dfsNumberCounter++;
	S.push_back(u);
	visited[u]=1;

	if(cnt[u] == 1){
		int v = u^(sz-1);
		if(dfs_num[v]==-1){
			tarjanSCC(v);
		}
		if(visited[v]==1){
			dfs_low[u]=min(dfs_low[u],dfs_low[v]);
		}
	}
	for(int j=0;j<n;j++){
		if(u&(1<<j)){
			int v = u^(1<<j);
			if(dfs_num[v]==-1){
				tarjanSCC(v);
			}
			if(visited[v]==1){
				dfs_low[u]=min(dfs_low[u],dfs_low[v]);
			}
		}
	}

	if(dfs_low[u]==dfs_num[u]){
		Scc.push_back(vector<int>(0,0));
		while(true){
			int v= S.back();
			S.pop_back();
			visited[v]=0;
			Scc[numSCC].push_back(v);
			if(u==v) break;
		}
		numSCC++;
	}
}

int main(){

	cin>>n>>m;
	sz  = (1<<n);
	cnt.assign(1<<n,0);
	for(int i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}

	dfs_num.assign(sz,-1);
	dfs_low.assign(sz,0);
	visited.assign(sz,0);
	for(int i=0;i<sz;i++){
		if(dfs_num[i]==-1){
			tarjanSCC(i);
		}
	}

	int cc = 0;
	for(int i=0;i<(int)Scc.size();i++){
		bool flag = false;
		for(int j=0;j<(int)Scc[i].size();j++){
			//cout<<Scc[i][j]<<" ";
			if(cnt[Scc[i][j]]) flag = true;
		}
		//cout<<endl;
		if(flag) cc++;
	}
	cout<<cc<<endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<cstdlib>
#include<complex>
#include<list>
#include<cassert>
#include<iomanip>
#include<limits>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;
typedef vector<int> vi;
long long mod = 1000000009LL;
long long large = 2000000000000000000LL;

int n,m;
int sz;

int dfs_num[1<<22],dfs_low[1<<22],visited[1<<22],cnt[1<<22];
vector<int> S;
vector<vector<int> > Scc;
int dfsNumberCounter = 0, numSCC = 0;
void tarjanSCC(int u){
	dfs_low[u]=dfs_num[u]=dfsNumberCounter++;
	S.push_back(u);
	visited[u]=1;

	if(cnt[u] == 1){
		int v = u^(sz-1);
		if(dfs_num[v]==-1){
			tarjanSCC(v);
		}
		if(visited[v]==1){
			dfs_low[u]=min(dfs_low[u],dfs_low[v]);
		}
	}
	for(int j=0;j<n;j++){
		if(u&(1<<j)){
			int v = u^(1<<j);
			if(dfs_num[v]==-1){
				tarjanSCC(v);
			}
			if(visited[v]==1){
				dfs_low[u]=min(dfs_low[u],dfs_low[v]);
			}
		}
	}

	if(dfs_low[u]==dfs_num[u]){
		Scc.push_back(vector<int>(0,0));
		while(true){
			int v= S.back();
			S.pop_back();
			visited[v]=0;
			Scc[numSCC].push_back(v);
			if(u==v) break;
		}
		numSCC++;
	}
}

int main(){

	cin>>n>>m;
	sz  = (1<<n);
	for(int i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}

	for(int i=0;i<sz;i++) dfs_num[i] = -1;
	for(int i=0;i<sz;i++) dfs_low[i] = visited[i] = 0;

	for(int i=0;i<sz;i++){
		if(dfs_num[i]==-1){
			tarjanSCC(i);
		}
	}

	int cc = 0;
	for(int i=0;i<(int)Scc.size();i++){
		bool flag = false;
		for(int j=0;j<(int)Scc[i].size();j++){
			//cout<<Scc[i][j]<<" ";
			if(cnt[Scc[i][j]]) flag = true;
		}
		//cout<<endl;
		if(flag) cc++;
	}
	cout<<cc<<endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<cstdlib>
#include<complex>
#include<list>
#include<cassert>
#include<iomanip>
#include<limits>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;
typedef vector<int> vi;
long long mod = 1000000009LL;
long long large = 2000000000000000000LL;

int n,m;
vector<int> cnt;
int sz;

vector<int> dfs_num,dfs_low,S,visited;
vector<vector<int> > adj;
vector<vector<int> > Scc;
int dfsNumberCounter = 0, numSCC = 0;
void tarjanSCC(int u){
	dfs_low[u]=dfs_num[u]=dfsNumberCounter++;
	S.push_back(u);
	visited[u]=1;

	if(cnt[u] == 1){
		int v = u^(sz-1);
		if(dfs_num[v]==-1){
			tarjanSCC(v);
		}
		if(visited[v]==1){
			dfs_low[u]=min(dfs_low[u],dfs_low[v]);
		}
	}
	for(int j=0;j<n;j++){
		if(u&(1<<j)){
			int v = u^(1<<j);
			if(dfs_num[v]==-1){
				tarjanSCC(v);
			}
			if(visited[v]==1){
				dfs_low[u]=min(dfs_low[u],dfs_low[v]);
			}
		}
	}

	if(dfs_low[u]==dfs_num[u]){
		Scc.push_back(vector<int>(0,0));
		while(true){
			int v= S.back();
			S.pop_back();
			visited[v]=0;
			Scc[numSCC].push_back(v);
			if(u==v) break;
		}
		numSCC++;
	}
}

int main(){

	cin>>n>>m;
	sz  = (1<<n);
	cnt.assign(1<<n,0);
	for(int i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}
	adj.assign(sz,vector<int>());

	dfs_num.assign(sz,-1);
	dfs_low.assign(sz,0);
	visited.assign(sz,0);
	for(int i=0;i<sz;i++){
		if(dfs_num[i]==-1){
			tarjanSCC(i);
		}
	}

	int cc = 0;
	for(int i=0;i<(int)Scc.size();i++){
		bool flag = false;
		for(int j=0;j<(int)Scc[i].size();j++){
			//cout<<Scc[i][j]<<" ";
			if(cnt[Scc[i][j]]) flag = true;
		}
		//cout<<endl;
		if(flag) cc++;
	}
	cout<<cc<<endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<cstdlib>
#include<complex>
#include<list>
#include<cassert>
#include<iomanip>
#include<limits>

using namespace std;

#define double long double

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
typedef pair<int,ii> iii2;
typedef pair<ii,ii> iiii;
typedef vector<int> vi;
long long mod = 1000000009LL;
long long large = 2000000000000000000LL;

vector<int> dfs_num,dfs_low,S,visited;
vector<vector<int> > adj;
vector<vector<int> > Scc;
int dfsNumberCounter = 0, numSCC = 0;
void tarjanSCC(int u){
	dfs_low[u]=dfs_num[u]=dfsNumberCounter++;
	S.push_back(u);
	visited[u]=1;
	for(int j=0;j<(int)adj[u].size();j++){
		int v = adj[u][j];
		if(dfs_num[v]==-1){
			tarjanSCC(v);
		}
		if(visited[v]==1){
			dfs_low[u]=min(dfs_low[u],dfs_low[v]);
		}
	}

	if(dfs_low[u]==dfs_num[u]){
		Scc.push_back(vector<int>(0,0));
		while(true){
			int v= S.back();
			S.pop_back();
			visited[v]=0;
			Scc[numSCC].push_back(v);
			if(u==v) break;
		}
		numSCC++;
	}
}

int n,m;
vector<int> cnt;
int sz;
int main(){

	cin>>n>>m;
	sz  = (1<<n);
	cnt.assign(1<<n,0);
	for(int i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}
	adj.assign(sz,vector<int>());
	for(int i=0;i<sz;i++){
		for(int j=0;j<n;j++){
			if(i&(1<<j)){
				int v = i^(1<<j);
				adj[i].push_back(v);
			}
		}
	}

	for(int i=0;i<sz;i++){
		if(cnt[i]){
			adj[i].push_back(i^(sz-1));
		}
	}

	dfs_num.assign(sz,-1);
	dfs_low.assign(sz,0);
	visited.assign(sz,0);
	for(int i=0;i<sz;i++){
		if(dfs_num[i]==-1){
			tarjanSCC(i);
		}
	}

	int cc = 0;
	for(int i=0;i<(int)Scc.size();i++){
		bool flag = false;
		for(int j=0;j<(int)Scc[i].size();j++){
			//cout<<Scc[i][j]<<" ";
			if(cnt[Scc[i][j]]) flag = true;
		}
		//cout<<endl;
		if(flag) cc++;
	}
	cout<<cc<<endl;

	return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

vector<vector<int>> scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	return scc; // in reverse topological order
}

const int MAXN = 5e6 + 100;

bool ok[MAXN];

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int N, M;
    cin >> N >> M;

    int tam = (1<<N)*2+M;

    graph G(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}

    	G.add_edge(M+mask,M+(1<<N)+inv);
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x))
    		{
    			G.add_edge(M+(mask^(1<<x)), M+mask);
    			G.add_edge(M+(1<<N)+mask, M+(1<<N)+(mask^(1<<x)));
    		}
    	}
    }

    db(G.adj);

    vector<vector<int>> vect = scc_gabow(G);

    for(int i = 0 ; i < vect.size() ; i++)
    {
    	for(auto x : vect[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

int A[MAXN];
int B[MAXN];

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	A[i] = n;
    	B[n] = i;
    	// G.add_edge(i,M+n);
    	// G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	// G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;
				for(auto v : G.adj[u])
				{
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(u < M)
				{
					int v = M+A[u];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
					int inv = (u-M);
			    	for(int x = 0 ; x < N ; x++)
			    	{
			    		inv = inv^(1<<x);
			    	}
			    	int v = M+(1<<N)+inv;
			 		if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}

					int v = B[u-M-(1<<N)];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

vector<vector<int>> scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	return scc; // in reverse topological order
}

const int MAXN = 5e6 + 100;

bool ok[MAXN];

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int N, M;
    cin >> N >> M;

    int tam = (1<<N)*2+M;

    graph G(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x))
    		{
    			G.add_edge(M+(mask^(1<<x)), M+mask);
    			G.add_edge(M+(1<<N)+mask, M+(1<<N)+(mask^(1<<x)));
    		}
    	}
    }

    vector<vector<int>> vect = scc_gabow(G);

    for(int i = 0 ; i < vect.size() ; i++)
    {
    	for(auto x : vect[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 5e6 + 100;

bool ok[MAXN];

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

void scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	for(int i = 0 ; i < scc.size() ; i++)
    {
    	for(auto x : scc[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    graph G(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x))
    		{
    			G.add_edge(M+(mask^(1<<x)), M+mask);
    			G.add_edge(M+(1<<N)+mask, M+(1<<N)+(mask^(1<<x)));
    		}
    	}
    }

    scc_gabow(G);

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

bool in[MAXN];

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	in[n] = true;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;
				for(auto v : G.adj[u])
				{
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				// if(u < M)
				// {

				// }
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

int A[MAXN];
int B[MAXN];

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	A[i] = n;
    	B[n] = i;
    	// G.add_edge(i,M+n);
    	// G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;
				for(auto v : G.adj[u])
				{
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(u < M)
				{
					int v = M+A[u];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}

					int v = B[u-M-(1<<N)];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

int A[MAXN];

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	A[i] = n;
    	// G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;
				for(auto v : G.adj[u])
				{
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(u < M)
				{
					int v = M+A[u];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

void scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if(M <= u && u < M+(1<<N))
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M)&(1<<x));
				else
				{
					int v = ((u-M)^(1<<x))+M;
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}
		if(M+(1<<N) <= u)
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M-(1<<N))&(1<<x))
				{
					int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	for(int i = 0 ; i < scc.size() ; i++)
    {
    	for(auto x : scc[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }
}

int comp = 1;

void DFS(int u)
{
	if(u < M)ok[comp] = true;
	mk[u] = true;
	for(auto v : G.adj[u])
	{
		if(!mk[v])
		{
			DFS(v);
		}
	}
	if(M <= u && u < M+(1<<N))
	{
		for(int x = 0 ; x < N ; x++)
		{
			if((u-M)&(1<<x));
			else
			{
				int v = ((u-M)^(1<<x))+M;
				if(!mk[v])
				{
					DFS(v);
				}
			}
		}
	}
	if(M+(1<<N) <= u)
	{
		for(int x = 0 ; x < N ; x++)
		{
			if((u-M-(1<<N))&(1<<x))
			{
				int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
				if(!mk[v])
				{
					DFS(v);
				}
			}
		}
	}
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;
    		DFS(i);
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

void scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if(M <= u && u < M+(1<<N))
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M)&(1<<x));
				else
				{
					int v = ((u-M)^(1<<x))+M;
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}
		if(M+(1<<N) <= u)
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M-(1<<N))&(1<<x))
				{
					int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	for(int i = 0 ; i < scc.size() ; i++)
    {
    	for(auto x : scc[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    graph G(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x))
    		{
    			// G.add_edge(M+(mask^(1<<x)), M+mask);
    			// G.add_edge(M+(1<<N)+mask, M+(1<<N)+(mask^(1<<x)));
    		}
    	}
    }

    scc_gabow(G);

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
};

void scc_gabow(graph &adj)
{
	int n = adj.n;

	vector<vector<int>> scc;
	vector<int> S, B, I(n);

	function<void(int)> dfs = [&](int u)
	{
		B.push_back(I[u] = S.size());
		S.push_back(u);

		for (int v : adj[u])
			if (!I[v]) dfs(v);
			else while (I[v] < B.back()) B.pop_back();

		if(M <= u && u < M+(1<<N))
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M)&(1<<x));
				else
				{
					int v = ((u-M)^(1<<x))+M;
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}
		if(M+(1<<N) <= u)
		{
			for(int x = 0 ; x < N ; x++)
			{
				if((u-M-(1<<N))&(1<<x))
				{
					int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
					if (!I[v]) dfs(v);
					else while (I[v] < B.back()) B.pop_back();
				}
			}
		}

		if (I[u] == B.back())
		{
			scc.push_back({});
			for (B.pop_back(); I[u] < S.size(); S.pop_back())
			{
				scc.back().push_back(S.back());
				I[S.back()] = n + scc.size();
			}
		}
	};

	for (int u = 0; u < n; ++u)
		if (!I[u]) dfs(u);

	for(int i = 0 ; i < scc.size() ; i++)
    {
    	for(auto x : scc[i])
    	{
    		if(x < M)
    		{
    			ok[i+1] = true;
    		}
    	}
    }
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    graph G(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    scc_gabow(G);

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

struct graph
{
	int n;
	vector<vector<int>> adj;

	graph(int n) : n(n), adj(n) {}

	void add_edge(int u, int v)
	{
		adj[u].push_back(v);
	}

	vector<int>& operator[](int u) { return adj[u]; }
}G((1<<22)*3);

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	G.add_edge(i,M+n);
    	G.add_edge(M+(1<<N)+n,i);
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	int inv = mask;
    	for(int x = 0 ; x < N ; x++)
    	{
    		inv = inv^(1<<x);
    	}
    	G.add_edge(M+mask,M+(1<<N)+inv);
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;
				for(auto v : G.adj[u])
				{
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}


#include <bits/stdc++.h>

#define int long long

using namespace std;

const int MAXN = 5e6 + 100;

#ifdef LOCAL
#include "/media/brayand/BrayanD/debugger.h"
#else
#define db(...) false
#define dbg(...) false
#endif

vector<int> L[MAXN];

int dp1[MAXN][2];
int dp2[MAXN][2];

bool mk[MAXN];

bool mark[MAXN];

void DFS(int nodo)
{
	mark[nodo] = true;
	for(auto v : L[nodo])
	{
		if(!mark[v])
		{
			DFS(v);
		}
	}
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0 ; i < MAXN ; i++)
    {
    	dp1[i][0] = 1e18;
    	dp1[i][1] = -1e18;
    	dp2[i][0] = 1e18;
    	dp2[i][1] = -1e18;
    }

    int N, M;
    cin >> N >> M;

    for(int i = 1 ; i <= M ; i++)
    {
    	int n;
    	cin >> n;
    	mk[n] = true;
    	dp1[n][0] = n;
    	dp1[n][1] = n;

    	int inv = n;
		for(int x = 0 ; x < N ; x++)
		{
			inv = inv^(1<<x);
		}

    	dp2[n][0] = inv;
    	dp2[n][1] = inv;
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x))
    		{
    			dp1[mask][0] = min(dp1[mask][0], dp1[mask^(1<<x)][0]);
    			dp1[mask][1] = max(dp1[mask][1], dp1[mask^(1<<x)][1]);
    		}
    	}
    }

    for(int mask = (1<<N)-1 ; mask >= 0 ; mask--)
    {
    	for(int x = 0 ; x < N ; x++)
    	{
    		if(mask&(1<<x));
    		else
    		{
    			dp2[mask][0] = min(dp2[mask][0], dp2[mask^(1<<x)][0]);
    			dp2[mask][1] = max(dp2[mask][1], dp2[mask^(1<<x)][1]);
    		}
    	}
    }

    for(int mask = 0 ; mask < (1<<N) ; mask++)
    {
    	if(mk[mask])
    	{
    		int inv = mask;
    		for(int x = 0 ; x < N ; x++)
    		{
    			inv = inv^(1<<x);
    		}
    		if(dp1[inv][0] != 1e18)L[mask].push_back(dp1[inv][0]);
    		if(dp1[inv][1] != -1e18)L[mask].push_back(dp1[inv][1]);
    		if(dp2[inv][0] != 1e18)L[mask].push_back(dp2[inv][0]);
    		if(dp2[inv][1] != -1e18)L[mask].push_back(dp2[inv][1]);
    		db(inv);
    		db(mask);
    		db(L[mask]);
    	}
    }

    int cont = 0;

    for(int i = 0 ; i < (1<<N) ; i++)
    {
    	if(mk[i] == false)continue;

    	if(mark[i] == false)
    	{
    		DFS(i);
    		cont++;
    	}
    }

    cout << cont << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 5e6 + 100;

bool ok[MAXN];

vector<bool> mk;

int N, M;

int A[MAXN];
int B[MAXN];

int comp = 1;

queue<int> Q;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M;

    int tam = (1<<N)*2+M;

    mk.resize(tam);

    for(int i = 0 ; i < M ; i++)
    {
    	int n;
    	cin >> n;
    	A[i] = n;
    	B[n] = i;
    }

    for(int i = 0 ; i < M ; i++)
    {
    	if(!mk[i])
    	{
    		comp++;

    		Q.push(i);
    		mk[i] = true;

    		while(Q.size())
    		{
    			int u = Q.front();
    			Q.pop();
				if(u < M)ok[comp] = true;
				mk[u] = true;

				if(u < M)
				{
					int v = M+A[u];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M <= u && u < M+(1<<N))
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M)&(1<<x));
						else
						{
							int v = ((u-M)^(1<<x))+M;
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}
					int inv = (u-M);
			    	for(int x = 0 ; x < N ; x++)
			    	{
			    		inv = inv^(1<<x);
			    	}
			    	int v = M+(1<<N)+inv;
			 		if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
				if(M+(1<<N) <= u)
				{
					for(int x = 0 ; x < N ; x++)
					{
						if((u-M-(1<<N))&(1<<x))
						{
							int v = ((u-M-(1<<N))^(1<<x))+M+(1<<N);
							if(!mk[v])
							{
								Q.push(v);
								mk[v] = true;
							}
						}
					}

					int v = B[u-M-(1<<N)];
					if(!mk[v])
					{
						Q.push(v);
						mk[v] = true;
					}
				}
    		}
    	}
    }

    int res = 0;

    for(int i = 0 ; i < MAXN ; i++)
    {
    	if(ok[i])res++;
    }

    cout << res << '\n';

    return 0;
}