#include <bits/stdc++.h>
using namespace std;
const int mxn = 10;
class Data {
 public:
  const int k;
  int sz;
  std::vector<int> mn, mx;
  Data(int _k) : k(_k), sz(1), mn(k), mx(k) {
    for (int i = (0); i != int(k); ++i) {
      mn[i] = mx[i] = (*std::istream_iterator<int>(cin));
    }
  }
  bool merge(const Data& rhs) {
    if (std::inner_product((mn).begin(), (mn).end(), rhs.mx.begin(), false,
                           std::bit_or<bool>(), std::less<int>()) and
        std::inner_product((mx).begin(), (mx).end(), rhs.mn.begin(), false,
                           std::bit_or<bool>(), std::greater<int>())) {
      sz += rhs.sz;
      for (int i = (0); i != int(k); ++i) {
        mn[i] = std::min(mn[i], rhs.mn[i]);
        mx[i] = std::max(mx[i], rhs.mx[i]);
      }
      return true;
    } else
      return false;
  }
  inline bool operator<(const Data& rhs) const {
    return mn.front() < rhs.mn.front();
  }
};
int main() {
  cin.sync_with_stdio(0);
  int n = (*std::istream_iterator<int>(cin));
  int k = (*std::istream_iterator<int>(cin));
  std::set<Data> s;
  for (int i = (0); i != int(n); ++i) {
    Data d(k);
    while (!s.empty()) {
      auto it = s.lower_bound(d);
      if (it != s.end() and d.merge(*it)) {
        s.erase(it);
        continue;
      }
      if (it != s.begin() and d.merge(*--it)) {
        s.erase(it);
        continue;
      }
      break;
    }
    s.insert(std::move(d));
    printf("%d\n", (--s.end())->sz);
  }
}
