# Clique

$n ≤ 3000$

## 题解

CO int N=3e3+10,L=1e6;
int tree[4*N],tag[4*N];

#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
IN void put_tag(int x,int v){
tree[x]+=v,tag[x]+=v;
}
IN void push_down(int x){
if(tag[x]){
put_tag(lc,tag[x]),put_tag(rc,tag[x]);
tag[x]=0;
}
}
void build(int x,int l,int r){
tree[x]=tag[x]=0;
if(l==r) return;
build(lc,l,mid),build(rc,mid+1,r);
}
void insert(int x,int l,int r,int p,int v){
if(l==r) {tree[x]=v; return;}
push_down(x);
if(p<=mid) insert(lc,l,mid,p,v);
else insert(rc,mid+1,r,p,v);
tree[x]=max(tree[lc],tree[rc]);
}
void modify(int x,int l,int r,int ql,int qr,int v){
if(ql<=l and r<=qr) return put_tag(x,v);
push_down(x);
if(ql<=mid) modify(lc,l,mid,ql,qr,v);
if(qr>mid) modify(rc,mid+1,r,ql,qr,v);
tree[x]=max(tree[lc],tree[rc]);
}
int query(int x,int l,int r,int ql,int qr){
if(ql<=l and r<=qr) return tree[x];
push_down(x);
if(qr<=mid) return query(lc,l,mid,ql,qr);
if(ql>mid) return query(rc,mid+1,r,ql,qr);
return max(query(lc,l,mid,ql,qr),query(rc,mid+1,r,ql,qr));
}
#undef lc
#undef rc
#undef mid

int a[N],b[N];

void real_main(){
int ans=0;
for(int w=1;w<=n;++w){
vector<tuple<int,int,int> > p;
for(int i=1;i<=n;++i)if(i!=w){
bool l=0,r=0;
if(a[i]<=b[i]){
if(a[i]<=a[w] and a[w]<=b[i]) l=1;
if(a[i]<=b[w] and b[w]<=b[i]) r=1;
}
else{
if(a[i]<=a[w] or a[w]<=b[i]) l=1;
if(a[i]<=b[w] or b[w]<=b[i]) r=1;
}
else if(l){ // use a[w] as origin
int x=(b[i]+L-a[w])%L;
int y=(a[w]+L-a[i])%L;
p.emplace_back(x,1,y);
}
else if(r){
int x=(a[i]+L-a[w])%L;
int y=(a[w]+L-b[i])%L;
p.emplace_back(x,0,y);
} // invalid if x1<x0 and y1<y0
}
if(p.size()){
sort(p.begin(),p.end());
vector<int> d;
for(CO tuple<int,int,int>&t:p) d.push_back(get<2>(t));
sort(d.begin(),d.end());
d.erase(unique(d.begin(),d.end()),d.end());
build(1,1,d.size());
for(tuple<int,int,int>&t:p)
get<2>(t)=lower_bound(d.begin(),d.end(),get<2>(t))-d.begin()+1;
for(CO tuple<int,int,int>&t:p){
int y=get<2>(t);
if(get<1>(t)){
if(1<=y-1) modify(1,1,d.size(),1,y-1,1);
insert(1,1,d.size(),y,query(1,1,d.size(),y,d.size())+1);
}
else modify(1,1,d.size(),y,d.size(),1);
}
}