将列的状态作为 bitmask $i$,记 $a_i$ 表示状态为 $i$ 的列的出现次数,$\operatorname{pop}(i)=\min(\operatorname{popcount}(i),n-\operatorname{popcount}(i))$。

枚举行的翻转状态为 bitmask $k$。记行的翻转状态为 $k$ 时,$1$ 的数量为 $f(k)$,那么最终答案就是

\[\min_{k\in[0,1]^n}f(k)\]

其中

\[f(k)=\sum_{i\in[0,1]^n}a_i\times\operatorname{pop}(i\oplus k)\]

换元,令 $j=i\oplus k$,则 $i\oplus j=k$

\[\begin{aligned} f(k)&=\sum_{i\in[0,1]^n}a_i\times\operatorname{pop}(i\oplus k)\\ &=\sum_{i\oplus j=k}a_i\times\operatorname{pop}(j)\\ \end{aligned}\]

预处理出 $a,\operatorname{pop}$ 后 FWT 处理出 $f$ 即可,复杂度瓶颈来源于 FWT,为 $\mathcal O(n2^n)$。

#include<bits/stdc++.h>
#define siz(x) int((x).size())
#define all(x) std::begin(x),std::end(x)
#define fi first
#define se second
#define pop __builtin_popcount
using namespace std;
using unt=unsigned;
using loli=long long;
using lolu=unsigned long long;
using pii=pair<int,int>;
mt19937_64 rng(random_device{}());
constexpr int N=1e5+7,M=21,P=998244353,ny=(P+1)/2;
int n,m;
struct mint{
	int d;
	mint()=default;
	mint(int x):d(x){}
	friend std::istream&operator>>(std::istream&x,mint&y){return x>>y.d;}
	friend std::ostream&operator<<(std::ostream&x,mint y){return x<<y.d;}
	friend mint operator+(mint x,mint y){return (x.d+=y.d)<P?x.d:x.d-P;}
	mint&operator+=(mint z){return (d+=z.d)<P?d:d-=P,*this;}
	friend mint operator-(mint x,mint y){return (x.d-=y.d)<0?x.d+P:x.d;}
	mint&operator-=(mint z){return (d-=z.d)<0?d+=P:d,*this;}
	friend mint operator*(mint x,mint y){return int(1ll*x.d*y.d%P);}
	mint&operator*=(mint z){return d=int(1ll*d*z.d%P),*this;}
	static mint qpow(int x,int y=P-2){int z=1;for(;y;y>>=1,x=int(1ll*x*x%P))if(y&1)z=int(1ll*x*z%P);return z;}
	friend mint operator/(mint x,mint y){return x*=qpow(y.d);}
	mint&operator/=(mint z){return (*this)*=qpow(z.d);}
	friend mint operator^(mint x,mint y){return qpow(x.d,y.d);}
	mint&operator^=(mint z){return *this=qpow(d,z.d);}
	mint operator()(mint z)const{return qpow(d,z.d);}
	mint&operator[](mint z){return *this=qpow(d,z.d);}
	mint inv()const{return qpow(d);}
	mint pow(mint z)const{return qpow(d,z.d);}
	int operator+()const{return d;}
	mint operator-()const{return d?P-d:0;}
	int operator~()const{return ~d;}
};
mint operator""_m(lolu x){return mint(int(x%P));}
string s[N];
mint a[1<<M],p[1<<M],f[1<<M];
void fwt_xor(mint *a){
	for(int i=0;i<m;i++)for(int j=0;j<(1<<m);j++)
		if(j>>i&1)tie(a[j^(1<<i)],a[j])=pair(a[j^(1<<i)]+a[j],a[j^(1<<i)]-a[j]);
}
void ifwt_xor(mint *a){
	for(int i=0;i<m;i++)for(int j=0;j<(1<<m);j++)
		if(j>>i&1)tie(a[j^(1<<i)],a[j])=pair((a[j^(1<<i)]+a[j])*ny,(a[j^(1<<i)]-a[j])*ny);
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	ios::sync_with_stdio(false);cin.tie(nullptr);
	cin>>m>>n;
	for(int i=1;i<=m;i++)cin>>s[i];
	for(int i=1;i<=n;i++){
		int x=0;
		for(int j=0;j<m;j++)if(s[j+1][i-1]=='1')
			x|=(1<<j);
		a[x].d++;
	}
	for(int k=0;k<(1<<m);k++)
		p[k]=min(pop(k),m-pop(k));
	fwt_xor(a);
	fwt_xor(p);
	for(int k=0;k<(1<<m);k++)
		f[k]=a[k]*p[k];
	ifwt_xor(f);
	int ans=0x3f3f3f3f;
	for(int k=0;k<(1<<m);k++)
		ans=min(ans,f[k].d);
	cout<<ans;
	return 0;
}