#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
class node {
 public:
  int size;
  vector<int> low, high;
  node(const vector<int>& v) : size(1), low(v), high(v) {}
  bool operator<(const node& a) const {
    for (int i = 0; i < (int)(low.size()); i++)
      if (high[i] > a.low[i]) return false;
    return true;
  }
  void merge(const node& a) {
    size += a.size;
    for (int i = 0; i < (int)(low.size()); i++) {
      low[i] = min(low[i], a.low[i]);
      high[i] = max(high[i], a.high[i]);
    }
  }
};
int main() {
  int n, k, a;
  scanf("%d", &n), scanf("%d", &k);
  set<node> chain;
  for (int i = 0; i < n; i++) {
    vector<int> v(10);
    for (int i = 0; i < k; i++) scanf("%d", &a), v.push_back(a);
    node N(v);
    auto eq = chain.lower_bound(N), gr = chain.upper_bound(N);
    while (eq != gr) {
      N.merge(*eq);
      eq = chain.erase(eq);
    }
    chain.insert(gr, N);
    printf("%d\n", chain.rbegin()->size);
  }
  return 0;
}
