#include <bits/stdc++.h>
namespace IO {
inline int rd() {
  int f = 1, x = 0;
  char s = getchar();
  while (!isdigit(s)) {
    if (s == '-') f = -1;
    s = getchar();
  }
  while (isdigit(s)) {
    x = (x << 1) + (x << 3) + (s ^ 48);
    s = getchar();
  }
  return x * f;
}
inline void wrt(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) wrt(x / 10);
  putchar(x % 10 ^ 48);
}
}  // namespace IO
using namespace std;
using namespace IO;
int n, k, cnt;
const int N = 5e4 + 10;
const int M = 15;
struct node {
  int size, low[M], upp[M];
  bool operator<(const node &nt) const {
    for (int i = 1; i <= k; ++i)
      if (this->upp[i] >= nt.low[i]) return 0;
    return 1;
  }
  inline void merge(const node &b) {
    this->size += b.size;
    for (int i = 1; i <= k; ++i) {
      this->upp[i] = max(this->upp[i], b.upp[i]);
      this->low[i] = min(this->low[i], b.low[i]);
    }
  }
  inline void clear() {
    memset(low, 0x3f, sizeof(low));
    memset(upp, 0, sizeof(upp));
    size = 0;
  }
} t;
set<node> s;
set<node>::iterator q[N];
int main() {
  n = rd();
  k = rd();
  for (int i = 1; i <= n; ++i) {
    t.clear();
    t.size = 1;
    for (int j = 1; j <= k; ++j) {
      int c = rd();
      t.low[j] = t.upp[j] = c;
    }
    set<node>::iterator pre = s.lower_bound(t);
    set<node>::iterator nxt = s.upper_bound(t);
    set<node>::iterator it;
    cnt = 0;
    for (it = pre; it != nxt; ++it) q[++cnt] = it;
    for (int j = 1; j <= cnt; ++j) {
      t.merge(*q[j]);
      s.erase(q[j]);
    }
    s.insert(t);
    wrt((*(--s.end())).size);
    putchar('\n');
  }
  return 0;
}
