#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep2(i, a, b) for(int i = (a); i <= (b); ++i)

short a[550][550];
int b[550];
char buff;
array<short, 1 << 22> dp, nxt;
int main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    while(1) {
        int n, m;
        cin >> n >> m;
        if(!n) return 0;
        rep(i, n) rep(j, m) {
            cin >> buff;
            a[i][j] = buff - '0';
        }
        if(n < m) {
            int ans = 0;
            rep(mask, 1 << n) {
                if(ans > __builtin_popcount(mask)) continue;
                rep(i, m) b[i] = 0;
                rep(i, n) {
                    if(1 << i & mask) { rep(j, m) b[j] ^= a[i][j]; }
                }
                rep(i, m) {
                    if(b[i]) break;
                    if(i == m - 1) ans = max(ans, (int)__builtin_popcount(mask));
                }
            }
            cout << ans << '\n';
        } else {
            rep(i, 1 << m) dp[i] = -1000;
            dp[0] = 0;
            rep(i, n) {
                int k = 0;
                rep(j, m) k ^= (1 << j) * a[i][j];
                rep(j, 1 << m) nxt[j] = dp[j];
                rep(mask, 1 << m) {
                    if(dp[mask] < 0) continue;
                    nxt[k ^ mask] = max<short>(nxt[k ^ mask], dp[mask] + 1);
                }
                swap(dp, nxt);
            }
            cout << dp[0] << '\n';
        }
    }
}

