#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
bool Max(T1& a, T2 b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T1, typename T2>
bool Min(T1& a, T2 b) {
  return a > b ? a = b, 1 : 0;
}
struct node {
  int prior;
  array<pair<int, int>, 10> key;
  node* l = 0;
  node* r = 0;
  int sz;
  node(array<pair<int, int>, 10> k, int sz_) : prior(rand()), key(k), sz(sz_) {}
  void push() {}
  void update() {
    if (l) {
    }
    if (r) {
    }
  }
};
typedef node* pnode;
void merge(pnode& p, pnode l, pnode r) {
  if (!l)
    p = r;
  else if (!r)
    p = l;
  else {
    if (l->prior > r->prior) {
      p = l;
      l->push();
      merge(l->r, l->r, r);
    } else {
      p = r;
      r->push();
      merge(r->l, l, r->l);
    }
    p->update();
  }
}
void split(pnode p, pnode& l, pnode& r, array<pair<int, int>, 10> k) {
  if (!p) {
    l = r = 0;
    return;
  }
  p->push();
  if (k <= p->key) {
    r = p;
    split(p->l, l, p->l, k);
  } else {
    l = p;
    split(p->r, p->r, r, k);
  }
  p->update();
}
void insert(pnode& p, pnode n) {
  if (!p) {
    p = n;
    return;
  }
  if (n->prior > p->prior) {
    split(p, n->l, n->r, n->key);
    p = n;
  } else {
    p->push();
    if (n->key < p->key) {
      insert(p->l, n);
    } else {
      insert(p->r, n);
    }
  }
  p->update();
}
void split1(pnode p, pnode& l, pnode& r, pnode k) {
  if (!p) {
    l = r = 0;
    return;
  }
  if (!k) {
    l = p, r = 0;
    return;
  }
  if (p->key >= k->key) {
    r = p;
    split1(p->l, l, p->l, k);
  } else {
    l = p;
    split1(p->r, p->r, r, k);
  }
  p->update();
}
void split2(pnode p, pnode& l, pnode& r, pnode k) {
  if (!p) {
    l = r = 0;
    return;
  }
  if (!k) {
    l = 0, r = p;
    return;
  }
  if (p->key > k->key) {
    r = p;
    split2(p->l, l, p->l, k);
  } else {
    l = p;
    split2(p->r, p->r, r, k);
  }
  p->update();
}
pnode findmaxbeat(pnode p, int v, int k) {
  if (!p) return 0;
  if (p->key[k].first <= v) {
    pnode ret = findmaxbeat(p->r, v, k);
    if (ret) return ret;
    return p;
  }
  return findmaxbeat(p->l, v, k);
}
pnode findminbeaten(pnode p, int v, int k) {
  if (!p) return 0;
  if (p->key[k].second >= v) {
    pnode ret = findminbeaten(p->l, v, k);
    if (ret) return ret;
    return p;
  }
  return findminbeaten(p->r, v, k);
}
int getmaxsz(pnode p) {
  if (p->r) return getmaxsz(p->r);
  return p->sz;
}
int getsum(pnode p) {
  if (!p) return 0;
  int ret = p->sz;
  ret += getsum(p->l);
  ret += getsum(p->r);
  return ret;
}
const int N = 200001, inf = 1e9;
void solve() {
  int n, k;
  cin >> n >> k;
  pnode root = 0;
  while (n--) {
    array<pair<int, int>, 10> key;
    pnode mn = 0, mx = 0;
    for (int ki = 0; ki < (k); ++ki) {
      cin >> key[ki].first;
      key[ki].second = key[ki].first;
      pnode curmn = findminbeaten(root, key[ki].first, ki);
      if (curmn && (!mn || curmn->key < mn->key)) mn = curmn;
      pnode curmx = findmaxbeat(root, key[ki].first, ki);
      if (curmx && (!mx || mx->key < curmx->key)) mx = curmx;
    }
    for (int ki = 0; ki < (k); ++ki) {
      if (mn) Min(key[ki].first, mn->key[ki].first);
      if (mx) Max(key[ki].second, mx->key[ki].second);
    }
    pnode l, m, r;
    split1(root, l, r, mn);
    split2(r, m, r, mx);
    int sz = 1 + getsum(m);
    m = new node(key, sz);
    merge(root, l, m);
    merge(root, root, r);
    int ans = getmaxsz(root);
    cout << ans << '\n';
  }
}
void init() {}
int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(20);
  init();
  int TC = 1;
  for (int TI = 1; TI <= (TC); ++TI) {
    solve();
  }
  return 0;
}
