Monotone OR
设
暴力转移
设
可以发现需要半在线求
#include<bits/stdc++.h>
#define ri register int
#define fo(i,x,y) for(ri i=(x);i<=(y);++i)
#define fu(i,x,y) for(ri i=(x);i<(y);++i)
#define fd(i,x,y) for(ri i=(x);i>=(y);--i)
using namespace std;
const int N=(1<<24)+5,p=998244353;
int n,m,a[N],b[N],c[N],f[N],g[N];
inline void add(ri &x,ri y){if((x+=y)>=p)x-=p;}
inline void del(ri &x,ri y){if((x-=y)<0)x+=p;}
inline void sol(ri l,ri r,ri d){
if(r==l+1){
add(b[l],f[l]);
f[r]=g[l]=(1ll*a[l]*b[l]%p-c[l]+p)%p;
b[l]=f[l];c[l]=g[l];
return;
}
ri md=l+r>>1,u=1<<d;
sol(l,md,d-1);
fu(i,l,md){
add(b[i+(1<<d-1)],b[i]);
add(c[i+(1<<d-1)],c[i]);
}
sol(md,r,d-1);
fu(i,l,md){
add(b[i+(1<<d-1)],b[i]);
add(c[i+(1<<d-1)],c[i]);
}
}
int main(){
scanf("%d%d",&n,&m);
fo(i,1,m){
ri x;scanf("%d",&x);
++a[x];
}
ri w=1<<n;
fu(i,0,n)fu(j,0,w)
if(j>>i&1)add(a[j],a[j^(1<<i)]);
f[0]=1;sol(0,w,n);
printf("%d",f[w]);
}