#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
using ll = long long;
#define debug(x) #x << " = " << x << '\n'
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  int n, m;
  std::cin >> n >> m;
  std::vector<std::vector<int>> vote(n + 1, std::vector<int>(m, 0));
  std::vector<int> accept(m, 0);
  
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < m; j++) {
      std::cin >> vote[i][j];
      accept[j] += vote[i][j];
    }
  }
  std::vector<int> cnt((1 << m), 0);
  std::vector<int> one((1 << m), 0);
  auto dfs = [&](auto &&self, int mask, int i) {
    if (one[mask]) {
      return;
    }
    one[mask] = i;
    for (int j = 0; j < m; j++) {
      if ((mask >> j & 1)) {
        self(self, (mask ^ (1 << j)), i);
      }
    }
  };
  for (int i = 1; i <= n; i++) {
    int anti = 0;
    for (int j = 0; j < m; j++) {
      if (!vote[i][j]) {
        anti |= (1 << j);
      }
    }
    cnt[anti]++;
    dfs(dfs, anti, i);
  }
  
  for (int i = 0; i < m; i++) {
    for (int mask = (1 << m) - 1; mask >= 0; mask--) {
      if (!(mask >> i & 1)) {
        cnt[mask] += cnt[mask ^ (1 << i)];
      }
    }
  }
  std::vector<int> best2((1 << m), 0);
  for (int mask = 0; mask < (1 << m); mask++) {
    if (cnt[mask] >= 2) {
      best2[mask] = __builtin_popcount(mask);
    }
    for (int i = 0; i < m; i++) {
      if (mask >> i & 1) {
        best2[mask] = std::max(best2[mask], best2[mask ^ (1 << i)]);
      }
    }
  }
  std::vector<std::vector<int>> cntlen(m + 1, std::vector<int>((1 << m), 0));
  for (int mask = 0; mask < (1 << m); mask++) {
    if (cnt[mask] == 1) {
      cntlen[__builtin_popcount(mask)][mask]++;
    }
  }
  for (int len = 0; len <= m; len++) {
    for (int i = 0; i < m; i++) {
      for (int mask = 0; mask < (1 << m); mask++) {
        if (mask >> i & 1) {
          cntlen[len][mask] += cntlen[len][mask ^ (1 << i)];
        }
      }
    }
  }
  
  std::vector<std::vector<std::vector<int>>> minelen(m + 1, std::vector<std::vector<int>>(n + 1));
  for (int mask = 0; mask < (1 << m); mask++) {
    minelen[__builtin_popcount(mask)][one[mask]].push_back(mask);
  }
  
  for (int i = 1; i <= n; i++) {
    std::vector<int> care;
    int maskcare = 0;
    int yes = 0;
    for (int j = 0; j < m; j++) {
      int sz = accept[j] - vote[i][j];
      if (sz == n / 2) {
        maskcare |= (1 << j);
        care.push_back(j);
      } else if (sz > n / 2) {
        yes++;
      }
    } 
    // vr sa aleg cat mai multe din care a.i. intersectia e nevida si diferita de {i}
    int answer = best2[maskcare];
    for (int len = 1; len <= m; len++) {
      int with1 = cntlen[len][maskcare];
      for (int mask : minelen[len][i]) {
        if ((mask & maskcare) == mask) {
          with1--;
        }
      }
      if (with1) {
        answer = std::max(answer, len);
      }
    }
    // for (int mask = 0; mask < (1 << (int) care.size()); mask++) {
    //   int realmask = 0;
    //   for (int i = 0; i < (int) care.size(); i++) {
    //     if (mask >> i & 1) {
    //       realmask |= 1 << care[i];
    //     }
    //   }  
    //   if (cnt[realmask] == 1 && one[realmask] != i) {
    //     answer = std::max(answer, __builtin_popcount(mask));
    //   }
    // }
    std::cout << answer + yes << ' ';
  }
  
  return 0;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |