#include<iostream>
#include<algorithm>
const int sz=1e5+10;
struct item{
int a,b,c,id;
bool operator<(const item &x)const{
if(a!=x.a)return a<x.a;
if(b!=x.b)return b<x.b;
if(c!=x.c)return c<x.c;
return id<x.id;
}
bool operator==(const item &x)const{
return a==x.a&&b==x.b&&c==x.c;
}
}arr[sz];
int n,k,cnt[sz],f[sz];
struct SegT{
struct node{
int lson,rson,val;
}tree[sz<<8];
int num=0;
void add(int &p,int ln,int rn,int pos,int val){
if(p==0)p=++num;
tree[p].val+=val;
if(ln==rn)return;
int mid=ln+rn>>1;
if(pos<=mid)add(tree[p].lson,ln,mid,pos,val);
else add(tree[p].rson,mid+1,rn,pos,val);
}
int query(int p,int ln,int rn,int l,int r){
if(p==0)return 0;
if(ln>=l&&rn<=r)return tree[p].val;
int mid=ln+rn>>1,res=0;
if(l<=mid)res+=query(tree[p].lson,ln,mid,l,r);
if(r>mid)res+=query(tree[p].rson,mid+1,rn,l,r);
return res;
}
}segt;
struct ST{
int root[sz<<3];
void add(int p,int ln,int rn,int pos,int c,int val){
segt.add(root[p],1,k,c,val);
if(ln==rn)return;
int mid=ln+rn>>1;
if(pos<=mid)add(p<<1,ln,mid,pos,c,val);
else add(p<<1|1,mid+1,rn,pos,c,val);
}
int query(int p,int ln,int rn,int l,int r,int ql,int qr){
if(ln>=l&&rn<=r)return segt.query(root[p],1,k,ql,qr);
int mid=ln+rn>>1,res=0;
if(l<=mid)res+=query(p<<1,ln,mid,l,r,ql,qr);
if(r>mid)res+=query(p<<1|1,mid+1,rn,l,r,ql,qr);
return res;
}
}st;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n>>k;
for(int i=1,a,b,c;i<=n;i++)
std::cin>>a>>b>>c,arr[i]=item{a,b,c,i};
std::sort(arr+1,arr+n+1);
for(int i=1;i<=n;i++){
int b=arr[i].b,c=arr[i].c;
f[arr[i].id]+=st.query(1,1,k,1,b,1,c);
st.add(1,1,k,b,c,1);
}
for(int i=1;i<=n;i++)cnt[f[i]]++;
for(int i=0;i<n;i++)std::cout<<cnt[i]<<"\n";
return 0;
}