#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef vector VI; typedef pair PII; #define REP(i,s,t) for(int i=(s);i<(t);i++) #define FILL(x,v) memset(x,v,sizeof(x)) #define MAXN 30005 #define MAXM 20 char g[MAXN][MAXM + 1]; VI eng[MAXM]; int ok[MAXM + 1]; bool seen[MAXN]; int n, m; void solve(int j, int mSize, int seenCnt) { if (seenCnt < mSize) { // early break ok[mSize] = false; return; } if (!ok[mSize]) return; // early break if (j == m) return; solve(j + 1, mSize, seenCnt); VI unseen; for (auto &i: eng[j]) { if (!seen[i]) { seen[i] = true; seenCnt++; unseen.push_back(i); } } solve(j + 1, mSize + 1, seenCnt); for (auto &i: unseen) seen[i] = false; } int gmask[MAXN]; int main() { cin >> n >> m; REP(i,0,n) cin >> g[i]; unordered_map gmaskCnt; REP(i,0,n) { int gm = 0; REP(j,0,m) { if (g[i][j] == '1') gm |= 1 << j; } gmaskCnt[gm]++; } n = 0; for (auto &d: gmaskCnt) { int gm = d.first, cnt = d.second; cnt = min(cnt, m); while(cnt--) gmask[n++] = gm; } REP(j,0,m) { REP(i,0,n) if (gmask[i] & (1 << j)) eng[j].push_back(i); } FILL(ok, true); solve(0, 0, 0); int ans = 0; REP(k,0,m+1) { if (ok[k]) ans = k; else break; } cout << ans << endl; return 0; }