Problem:
Problem H
  Homework
Taro is a student of Ibaraki College of Prominent Computing. In this semester, he takes two courses, mathematics and informatics. After each class, the teacher may assign homework. Taro may be given multiple assignments in a single class, and each assignment may have a different deadline. Each assignment has a unique ID number.
Everyday after school, Taro completes at most one assignment as follows. First, he decides which course's homework to do at random by ipping a coin. Let $S$ be the set of all the unfinished assignments of the chosen course whose deadline has not yet passed. If $S$ is empty, he plays a video game without doing any homework on that day even if there are unfinished assignments of the other course. Otherwise, with $T \subseteq S$ being the set of assignments with the nearest deadline among $S$, he completes the one with the smallest assignment ID among $T$.
The number of assignments Taro will complete until the end of the semester depends on the result of coin ips. Given the schedule of homework assignments, your task is to compute the maximum and the minimum numbers of assignments Taro will complete.
Input
The input consists of a single test case in the following format.
$n$ $m$
$s_1$ $t_1$
...
$s_n$ $t_n$
The first line contains two integers $n$ and $m$ satisfying $1 \leq m < n \leq 400$. $n$ denotes the total number of assignments in this semester, and $m$ denotes the number of assignments of the mathematics course (so the number of assignments of the informatics course is $n - m$). Each assignment has a unique ID from $1$ to $n$; assignments with IDs $1$ through $m$ are those of the mathematics course, and the rest are of the informatics course. The next $n$ lines show the schedule of assignments. The $i$-th line of them contains two integers $s_i$ and $t_i$ satisfying $1 \leq s_i \leq t_i \leq 400$, which means that the assignment of ID $i$ is given to Taro on the $s_i$-th day of the semester, and its deadline is the end of the $t_i$-th day.
Output
In the first line, print the maximum number of assignments Taro will complete. In the second line, print the minimum number of assignments Taro will complete.
Sample Input 1
6 3
1 2
1 5
2 3
2 6
4 5
4 6
Sample Output 1
6
2
Sample Input 2
6 3
1 1
2 3
4 4
1 1
2 4
3 3
Sample Output 2
4
3

Submitted solutions:

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1LL << 60;
#define rep(i, a) for(ll i = 0; i < (a); i++)
#define all(a) begin(a), end(a)
#define sz(a) (a).size()
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
void out() { cout << endl; }
template<class T, class... Ts> void out(const T& a, const Ts&... b){ cout<<a; (cout<<... << (cout << ' ', b)); cout << endl;}
using vll = vector<ll>;
using vvll = vector<vll>;
using pll = pair<ll, ll>;
using ld = long double;

struct mf_graph
{
    struct Edge
    {
        int from, to;
        ll cap, flow;
    };
    int n;
    vector<Edge> Es;
    vector<vector<int>> g;
    mf_graph() = default;
    mf_graph(int _n) : n(_n), g(_n) {}
    void add(int a, int b, ll cap)
    {
        ll i = Es.size();
        Es.emplace_back(a, b, cap, 0);
        g[a].push_back(i);
        g[b].push_back(i);
    }
    ll flow(int s, int t, ll max_flow = INF)
    {
        ll ret = 0;
        while(true)
        {
            vector<int> dist(n, n + 1);
            queue<int> q;
            dist[s] = 0;
            q.push(s);
            bool fin = false;
            while(!q.empty())
            {
                int now = q.front(); q.pop();
                for(auto ie : g[now])
                {
                    auto [from, to, cap, flow] = Es[ie];
                    if(dist[from + to - now] < n + 1) continue;
                    if(from == now)
                    {
                        if(cap == flow) continue;
                        dist[to] = dist[from] + 1;
                        if(to == t)
                        {
                            fin = true;
                            break;
                        }
                        q.push(to);
                    }
                    else
                    {
                        if(flow == 0) continue;
                        dist[from] = dist[to] + 1;
                        if(from == t)
                        {
                            fin = true;
                            break;
                        }
                        q.push(from);
                    }
                }
                if(fin) break;
            }
            if(!fin) break;
            vector<pair<int, int>> ies;
            ll mn = max_flow - ret;
            ll now = t;
            while(now != s)
            {
                for(auto ie : g[now])
                {
                    auto [from, to, cap, flow] = Es[ie];
                    if(to == now)
                    {
                        if(flow == cap) continue;
                        if(dist[from] + 1 == dist[to])
                        {
                            now = from;
                            ies.emplace_back(ie, 1);
                            chmin(mn, cap - flow);
                            break;
                        }
                    }
                    else
                    {
                        if(flow == 0) continue;
                        if(dist[to] + 1 == dist[from])
                        {
                            now = to;
                            ies.emplace_back(ie, -1);
                            chmin(mn, flow);
                            break;
                        }
                    }
                }
            }
            for(auto [ie, dir] : ies)
            {
                if(dir == 1) Es[ie].flow += mn;
                else Es[ie].flow -= mn;
            }
            ret += mn;
        }
        return ret;
    }
};

int main()
{
    ll N, M; cin >> N >> M;
    vll S(N), T(N);
    rep(i, N) cin >> S[i] >> T[i];
    ll MX = *max_element(all(T));
    priority_queue<ll, vll, greater<ll>> pq;
    vvll ss(MX);
    rep(i, N) ss[S[i] - 1].push_back(T[i] - 1);
    ll ans = 0;
    rep(d, MX)
    {
        while(!pq.empty() && pq.top() < d) pq.pop();
        for(auto t : ss[d]) pq.emplace(t);
        if(!pq.empty())
        {
            ans++;
            pq.pop();
        }
    }
    out(ans);
    mf_graph mfg(N + 2*MX + 2);
    rep(i, M)
    {
        mfg.add(N+2*MX, i, 1);
        for(ll d = S[i] - 1; d <= T[i] - 1; d++)
        {
            mfg.add(i, N + d, 1);
        }
    }
    for(ll i = M; i < N; i++)
    {
        mfg.add(i, N+2*MX + 1, 1);
        for(ll d = S[i] - 1; d <= T[i] - 1; d++)
        {
            mfg.add(N + MX + d, i, 1);
        }
    }
    rep(d, MX) mfg.add(N + d, N + MX + d, 1);
    out(mfg.flow(N+2*MX, N+2*MX + 1));
}
accuracy: 1
time_ms: 10
memory_kb: 5356
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,a,b) for(ll i = a; i < b; i++)
#define per(i,a,b) for(ll i = b-1; i >= a; i--)
#define all(a) (a).begin(), (a).end()

ll sol1(int n,int m, vector<ll> s, vector<ll> t){
    vector<array<ll,2>> res(n);
    rep(i,0,n){
        res[i] = {s[i], t[i]};
    }
    sort(all(res));
    multiset<ll> ls;
    int i = 0;
    ll ans = 0;
    rep(day,0,501){
        while(i < n && day >= res[i][0]){
            ls.insert(res[i][1]);
            i++;
        }
        while(ls.size() && *ls.begin() < day){
            ls.erase(ls.begin());
        }
        if(ls.size()){
            ls.erase(ls.begin());
            ans++;
        }
    }
    return ans;
}

ll sol2(int n,int m, vector<ll> s, vector<ll> t){
    vector<ll> sa(m);
    vector<ll> ta(m);
    ll e=n-m;
    vector<ll> sb(e);
    vector<ll> tb(e);
    vector<vector<ll>> ssa(440);
    vector<vector<ll>> ssb(440);
    rep(i,0,m){
        sa[i]=s[i];
        ta[i]=t[i];
        ssa[sa[i]].push_back(ta[i]);
    }
    rep(i,0,e){
        sb[i]=s[i+m];
        tb[i]=t[i+m];
        ssb[sb[i]].push_back(tb[i]);
    }
    vector<vector<ll>> dp(430,vector<ll>(430,-1000000));
    dp[0][0]=0;
    rep(i,0,410){
        rep(j,0,410){
            
            if(i>=j){
                ll c=0;
                priority_queue<int,vector<int>,greater<int>> pq;
                rep(k,j,i){
                    rep(l,0,ssb[k].size()){
                        pq.push(ssb[k][l]);
                    }
                }
                if(pq.empty())dp[i][i]=max(dp[i][i],dp[i][j]);
                rep(k,i+1,415){
                    rep(l,0,ssb[k-1].size()){
                        pq.push(ssb[k-1][l]);
                    }
                    while(!pq.empty()&&k-1>pq.top())pq.pop();
                    if(!pq.empty())pq.pop();
                    else c++;
                    if(pq.empty()){dp[i][k]=max(dp[i][k],dp[i][j]+c);}
                }
            }
            if(j>=i){
                ll c=0;
                priority_queue<int,vector<int>,greater<int>> pq;
                rep(k,i,j){
                    rep(l,0,ssa[k].size()){
                        pq.push(ssa[k][l]);
                    }
                }
                if(pq.empty())dp[j][j]=max(dp[j][j],dp[i][j]);
                rep(k,j+1,415){
                    rep(l,0,ssa[k-1].size()){
                        pq.push(ssa[k-1][l]);
                    }
                    while(!pq.empty()&&k-1>pq.top())pq.pop();
                    if(!pq.empty())pq.pop();
                    else c++;
                    if(pq.empty()){dp[k][j]=max(dp[k][j],dp[i][j]+c);}
                }
                
            }
            
        }
    }
    return 404-dp[404][404];

}

int main(){
    int n,m;
    cin >> n >> m;
    vector<ll> s(n),t(n);
    rep(i,0,n){
        cin >> s[i] >> t[i];
    }
    cout << sol1(n,m,s,t) << endl;
    cout << sol2(n,m,s,t) << endl;
}
accuracy: 1
time_ms: 350
memory_kb: 4864
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct FordFulkerson{
	struct E{
		int from,to,rev,cap;
	};

	int n;
	vector<E> e;
	vector<vector<int>> ikeru;

	FordFulkerson(int _n): n(_n) {
		ikeru.resize(n);
	}

	void add_edge(int from, int to, int cap){
		int x = e.size();
		e.push_back({from, to, x + 1, cap});
		e.push_back({to, from, x, 0});
		ikeru[from].push_back(x);
		ikeru[to].push_back(x+1);
	}

	int max_flow(int st, int gl){
		int ans = 0;
		while(true){
			vector<int> mada = {st};
			vector<bool> tansaku(n);
			vector<int> cf(n, -1);
			tansaku[st] = 1;
			while(!mada.empty()){
				int i = mada.back();
				mada.pop_back();
				for (int x: ikeru[i]){
					if (e[x].cap == 0) continue;
					int j = e[x].to;
					if (tansaku[j]) continue;
					mada.push_back(j);
					tansaku[j] = true;
					cf[j] = x;
				}
			}
			if (!tansaku[gl]) break;
			int now = gl;
			int f = 1e9;
			while(now != st){
				f = min(f, e[cf[now]].cap);
				now = e[cf[now]].from;
			}
			ans += f;

			now = gl;
			while(now != st){
				e[cf[now]].cap -= f;
				e[e[cf[now]].rev].cap += f;
				now = e[cf[now]].from;
			}
		}	
		return ans;
	}
};

int main(){
	int n, m; cin >> n >> m;
	vector<int> s(n), t(n);
	for (int i=0; i<n; i++){
		cin >> s[i] >> t[i];
		s[i]--;
		t[i]--;
	}

	const int mx = 400;

	auto answer_max = [&]() -> int {
		vector bucket(mx, vector<int>(0));
		for (int i=0; i<n; i++){
			bucket[s[i]].push_back(t[i]);
		}

		int ret = 0;
		priority_queue<int> pq;

		for (int i=0; i<mx; i++){
			for (int x: bucket[i]){
				pq.push(-x);
			}

			while (!pq.empty()){
				int x = pq.top();
				pq.pop();
				x = -x;
				if (i <= x){
					ret++;
					break;
				}else{
					continue;
				}
			}
		}

		return ret;
	};

	auto answer_min = [&]() -> int {
		FordFulkerson mf(mx * 2 + n + 2);
		for (int i=0; i<mx; i++){
			mf.add_edge(i, mx + i, 1);
		}
		for (int i=0; i<m; i++){
			mf.add_edge(mx*2 + n, mx*2 + i, 1);
			for (int j=s[i]; j<=t[i]; j++){
				mf.add_edge(mx*2 + i, j, 1);
			}
		}
		for (int i=m; i<n; i++){
			mf.add_edge(mx*2 + i, mx*2 + n + 1, 1);
			for (int j=s[i]; j<=t[i]; j++){
				mf.add_edge(mx + j, mx*2 + i, 1);
			}
		}
		int ret = mf.max_flow(mx*2 + n, mx*2 + n + 1);
		return ret;
	};


	cout << answer_max() << '\n';
	cout << answer_min() << '\n';
}
accuracy: 1
time_ms: 20
memory_kb: 5596
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct FordFulkerson{
	struct E{
		int from,to,rev,cap;
	};
	int n;
	vector<E> e;
	vector<vector<int>> ikeru;

	FordFulkerson(int _n): n(_n) {
		ikeru.resize(n);
	}

	void add_edge(int from, int to, int cap){
		int x = e.size();
		e.push_back({from, to, x + 1, cap});
		e.push_back({to, from, x, 0});
		ikeru[from].push_back(x);
		ikeru[to].push_back(x+1);
	}

	int max_flow(int st, int gl){
		int ans = 0;
		while(true){
			vector<int> mada = {st};
			vector<bool> tansaku(n);
			vector<int> cf(n, -1);
			tansaku[st] = 1;
			while(!mada.empty()){
				int i = mada.back();
				mada.pop_back();
				for (int x: ikeru[i]){
					if (e[x].cap == 0) continue;
					int j = e[x].to;
					if (tansaku[j]) continue;
					mada.push_back(j);
					tansaku[j] = true;
					cf[j] = x;
				}
			}
			if (!tansaku[gl]) break;
			int now = gl;
			int f = 1e9;
			while(now != st){
				f = min(f, e[cf[now]].cap);
				now = e[cf[now]].from;
			}
			ans += f;

			now = gl;
			while(now != st){
				e[cf[now]].cap -= f;
				e[e[cf[now]].rev].cap += f;
				now = e[cf[now]].from;
			}
		}	
		return ans;
	}
};

int main(){
	int n, m; cin >> n >> m;
	vector<int> s(n), t(n);
	for (int i=0; i<n; i++){
		cin >> s[i] >> t[i];
		s[i]--;
		t[i]--;
	}

	const int mx = 400;

	auto answer_max = [&]() -> int {
		vector bucket(mx, vector<int>(0));
		for (int i=0; i<n; i++){
			bucket[s[i]].push_back(t[i]);
		}

		int ret = 0;
		priority_queue<int> pq;

		for (int i=0; i<mx; i++){
			for (int x: bucket[i]){
				pq.push(-x);
			}

			while (!pq.empty()){
				int x = pq.top();
				pq.pop();
				x = -x;
				if (i <= x){
					ret++;
					break;
				}else{
					continue;
				}
			}
		}

		return ret;
	};

	auto answer_min = [&]() -> int {
		FordFulkerson mf(mx * 2 + n + 2);
		for (int i=0; i<n; i++){
			mf.add_edge(i, mx + i, 1);
		}
		for (int i=0; i<m; i++){
			mf.add_edge(mx*2 + n, mx*2 + i, 1);
			for (int j=s[i]; j<=t[i]; j++){
				mf.add_edge(mx*2 + i, j, 1);
			}
		}
		for (int i=m; i<n; i++){
			mf.add_edge(mx*2 + i, mx*2 + n + 1, 1);
			for (int j=s[i]; j<=t[i]; j++){
				mf.add_edge(mx + j, mx*2 + i, 1);
			}
		}
		int ret = mf.max_flow(mx*2 + n, mx*2 + n + 1);
		return ret;
	};


	cout << answer_max() << '\n';
	cout << answer_min() << '\n';
}
accuracy: 0.036585365853658534
time_ms: 20
memory_kb: 5484
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,a,b) for(int i=(a);i<(b);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second

using vint=vector<int>;
using pint=pair<int,int>;
using vpint=vector<pint>;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
    ost<<"{"<<p.first<<","<<p.second<<"}";
    return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
    ost<<"{";
    for(int i=0;i<v.size();i++){
        if(i)ost<<",";
        ost<<v[i];
    }
    ost<<"}";
    return ost;
}


const int INF=1001001001;

const int V=400;

int N,M;
int S[444],T[444];

int calcMax(){
    vector<vint>lis(V);
    rep(i,N+M)lis[S[i]].pb(i);

    priority_queue<int,vint,greater<int>>que;
    int ans=0;
    for(int i=0;i<V;i++){
        for(auto k:lis[i])que.push(T[k]);
        while(que.size()&&que.top()<=i)que.pop();
        if(que.size()){
            ans++;
            que.pop();
        }
    }
    return ans;
}

bool ok[444];


vint calc(vpint &lis,vector<vint>&G,bool right){

    vector<vint>bucket(V);
    rep(i,lis.size())bucket[lis[i].fi].pb(i);

    priority_queue<pint,vector<pint>,greater<pint>>que;

    vint nex(V,-1),rev(lis.size(),-1),dom(V,-1);
    vpint mem(V);
    rep(i,V){
        for(auto k:bucket[i])que.emplace(lis[k].se,k);
        while(que.size()&&que.top().fi<=i)que.pop();

        if(ok[i]){
            auto p=que.top();
            que.pop();
            rev[p.se]=i;
            mem[i]=p;
        }

        if(que.size()){
            nex[i]=que.top().se;
        }
    }

    rep(i,V){
        if(!ok[i])continue;
        for(int j=i+1;j<V;j++){
            if(!ok[j])continue;
            if(mem[i].fi<=j)break;
            if(mem[i]<mem[j]){
                dom[i]=j;
                break;
            }
        }
    }

    
    vint ret;
    rep(i,V){
        if(ok[i])continue;
        int v=i;
        while(nex[v]!=-1&&rev[nex[v]]!=-1)v=rev[nex[v]];
        if(nex[v]!=-1)ret.pb(i);
    }

    rep(i,V){
        if(!ok[i])continue;
        vint check(V);
        int v=i;
        while(v!=-1){
            check[v]=true;
            int r;
            if(dom[v]==-1)r=V;
            else r=dom[v];
            for(int j=v+1;j<r;j++){
                if(ok[j])continue;
                if(mem[v].fi>j)check[j]=true;
            }
            v=dom[v];
        }
        vint dp(V);
        for(int j=V-1;j>=0;j--){
            dp[j]=check[j];
            if(nex[j]!=-1&&rev[nex[j]]!=-1)dp[j]|=dp[rev[nex[j]]];
            if(!ok[j]&&dp[j]){
                if(right){
                    G[j].pb(i);
                }
                else{
                    G[i].pb(j);
                }
            }
        }
    }
    return ret;
}

int calcMin(){
    vpint A,B;
    rep(i,M)A.eb(S[i],T[i]);
    rep(i,N)B.eb(S[i+M],T[i+M]);

    while(true){
        vector<vint>G(V);
        vint src=calc(A,G,false);
        vint snk=calc(B,G,true);
        

        vint dist(V,INF),pre(V,-1);
        queue<int>que;
        for(auto v:src){
            dist[v]=0;
            que.push(v);
        }
        while(que.size()){
            int v=que.front();
            que.pop();
            for(auto u:G[v]){
                if(dist[u]!=INF)continue;
                dist[u]=dist[v]+1;
                pre[u]=v;
                que.push(u);
            }
        }
        int nx=-1;
        for(auto v:snk){
            if(dist[v]==INF)continue;
            if(nx==-1||dist[nx]>dist[v])nx=v;
        }
        if(nx==-1)break;
        while(nx!=-1){
            ok[nx]^=1;
            nx=pre[nx];
        }
    }

    int ans=0;
    rep(i,V)if(ok[i])ans++;
    return ans;
}

signed main(){


    cin>>N>>M;
    N-=M;
    rep(i,N+M){
        cin>>S[i]>>T[i];
        S[i]--;
    }

    cout<<calcMax()<<endl;
    cout<<calcMin()<<endl;
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3540
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,a,b) for(int i=(a);i<(b);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second

using vint=vector<int>;
using pint=pair<int,int>;
using vpint=vector<pint>;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
    ost<<"{"<<p.first<<","<<p.second<<"}";
    return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
    ost<<"{";
    for(int i=0;i<v.size();i++){
        if(i)ost<<",";
        ost<<v[i];
    }
    ost<<"}";
    return ost;
}


const int INF=1001001001;

const int V=400;

int N,M;
int S[444],T[444];

int calcMax(){
    vector<vint>lis(V);
    rep(i,N+M)lis[S[i]].pb(i);

    priority_queue<int,vint,greater<int>>que;
    int ans=0;
    for(int i=0;i<V;i++){
        for(auto k:lis[i])que.push(T[k]);
        while(que.size()&&que.top()<=i)que.pop();
        if(que.size()){
            ans++;
            que.pop();
        }
    }
    return ans;
}

bool ok[444];


vint calc(vpint &lis,vector<vint>&G,bool right){
    vint ret;
    rep(t,2){
        vector<vint>bucket(V);
        rep(i,lis.size())bucket[lis[i].fi].pb(i);

        priority_queue<pint,vector<pint>,greater<pint>>que;

        vector<int>nex(V,-1),rev(lis.size(),-1);
        rep(i,V){
            for(auto k:bucket[i])que.emplace(lis[k].se,k);
            while(que.size()&&que.top().fi<=i)que.pop();

            if(ok[i]){
                auto p=que.top();
                que.pop();
                rev[p.se]=i;
            }

            if(que.size()){
                nex[i]=que.top().se;
            }
        }

        rep(i,V){
            if(ok[i])continue;
            vint vs{i};
            while(nex[vs.back()]!=-1&&rev[nex[vs.back()]]!=-1){
                vs.pb(rev[nex[vs.back()]]);
            }
            if(nex[vs.back()]!=-1){
                if(!t)ret.pb(i);
                else ret.pb(V-1-i);
            }
            else{
                for(int j=1;j<vs.size();j++){
                    if(!t){
                        if(right){
                            G[i].pb(vs[j]);
                        }
                        else{
                            G[vs[j]].pb(i);
                        }
                    }
                    if(t){
                        if(right){
                            G[V-1-i].pb(V-1-vs[j]);
                        }
                        else{
                            G[V-1-vs[j]].pb(V-1-i);
                        }
                    }
                }
            }
        }

        rep(i,lis.size()){
            lis[i]=pint(V-lis[i].se,V-lis[i].fi);
        }
        reverse(ok,ok+V);
    }
    sort(all(ret));ret.erase(unique(all(ret)),ret.end());
    return ret;
}

int calcMin(){
    vpint A,B;
    rep(i,M)A.eb(S[i],T[i]);
    rep(i,N)B.eb(S[i+M],T[i+M]);


    while(true){
        vector<vint>G(V);
        vint src=calc(A,G,false);
        vint snk=calc(B,G,true);
        rep(i,V){
            if(!ok[i])continue;
            for(auto v:src)G[i].pb(v);
            for(auto v:snk)G[v].pb(i);
        }

        vint dist(V,INF),pre(V,-1);
        queue<int>que;
        for(auto v:src){
            dist[v]=0;
            que.push(v);        }
        while(que.size()){
            int v=que.front();
            que.pop();
            for(auto u:G[v]){
                if(dist[u]!=INF)continue;
                dist[u]=dist[v]+1;
                pre[u]=v;
                que.push(u);
            }
        }
        int nx=-1;
        for(auto v:snk){
            if(dist[v]==INF)continue;
            if(nx==-1||dist[nx]>dist[v])nx=v;
        }
        if(nx==-1)break;
        while(nx!=-1){
            ok[nx]^=1;
            nx=pre[nx];
        }
    }

    int ans=0;
    rep(i,V)if(ok[i])ans++;
    return ans;
}

signed main(){


    cin>>N>>M;
    N-=M;
    rep(i,N+M){
        cin>>S[i]>>T[i];
        S[i]--;
    }

    cout<<calcMax()<<endl;
    cout<<calcMin()<<endl;
    return 0;
}
accuracy: 0.5121951219512195
time_ms: 80
memory_kb: 3632
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,a,b) for(int i=(a);i<(b);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second

using vint=vector<int>;
using pint=pair<int,int>;
using vpint=vector<pint>;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
    ost<<"{"<<p.first<<","<<p.second<<"}";
    return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
    ost<<"{";
    for(int i=0;i<v.size();i++){
        if(i)ost<<",";
        ost<<v[i];
    }
    ost<<"}";
    return ost;
}


const int INF=1001001001;

const int V=400;

int N,M;
int S[444],T[444];

int calcMax(){
    vector<vint>lis(V);
    rep(i,N+M)lis[S[i]].pb(i);

    priority_queue<int,vint,greater<int>>que;
    int ans=0;
    for(int i=0;i<V;i++){
        for(auto k:lis[i])que.push(T[k]);
        while(que.size()&&que.top()<=i)que.pop();
        if(que.size()){
            ans++;
            que.pop();
        }
    }
    return ans;
}

bool ok[400];


vint calc(vpint &lis,vector<vint>&G,bool right){
    vint ret;
    rep(t,2){
        vector<vint>bucket(V);
        rep(i,lis.size())bucket[lis[i].fi].pb(i);

        priority_queue<pint,vector<pint>,greater<pint>>que;

        vector<int>nex(V,-1),rev(lis.size(),-1);
        rep(i,V){
            for(auto k:bucket[i])que.emplace(lis[k].se,k);
            while(que.size()&&que.top().fi<=i)que.pop();

            if(ok[i]){
                auto p=que.top();
                que.pop();
                rev[p.se]=i;
            }

            if(que.size()){
                nex[i]=que.top().se;
            }
        }

        rep(i,V){
            if(ok[i])continue;
            vint vs{i};
            while(nex[vs.back()]!=-1&&rev[nex[vs.back()]]!=-1){
                vs.pb(rev[nex[vs.back()]]);
            }
            if(nex[vs.back()]!=-1){
                if(!t)ret.pb(i);
                else ret.pb(V-1-i);
            }
            for(int j=1;j<vs.size();j++){
                if(!t){
                    if(right){
                        G[i].pb(vs[j]);
                    }
                    else{
                        G[vs[j]].pb(i);
                    }
                }
                if(t){
                    if(right){
                        G[V-1-i].pb(V-1-vs[j]);
                    }
                    else{
                        G[V-1-vs[j]].pb(V-1-i);
                    }
                }
            }
        }

        rep(i,lis.size()){
            lis[i]=pint(V-lis[i].se,V-lis[i].fi);
        }
        reverse(ok,ok+V);
    }
    sort(all(ret));ret.erase(unique(all(ret)),ret.end());
    return ret;
}

int calcMin(){
    vpint A,B;
    rep(i,M)A.eb(S[i],T[i]);
    rep(i,N)B.eb(S[i+M],T[i+M]);


    while(true){
        vector<vint>G(V);
        vint src=calc(A,G,false);
        vint snk=calc(B,G,true);

        vint dist(V,INF),pre(V,-1);
        queue<int>que;
        for(auto v:src){
            dist[v]=0;
            que.push(v);
        }
        while(que.size()){
            int v=que.front();
            que.pop();
            for(auto u:G[v]){
                if(dist[u]!=INF)continue;
                dist[u]=dist[v]+1;
                pre[u]=v;
                que.push(u);
            }
        }
        int nx=-1;
        for(auto v:snk){
            if(dist[v]==INF)continue;
            if(nx==-1||dist[nx]>dist[v])nx=v;
        }
        if(nx==-1)break;
        while(nx!=-1){
            ok[nx]^=1;
            nx=pre[nx];
        }
    }

    int ans=0;
    rep(i,V)if(ok[i])ans++;
    return ans;
}

signed main(){


    cin>>N>>M;
    N-=M;
    rep(i,N+M){
        cin>>S[i]>>T[i];
        S[i]--;
    }

    cout<<calcMax()<<endl;
    cout<<calcMin()<<endl;
    return 0;
}
accuracy: 0.5121951219512195
time_ms: 50
memory_kb: 3392
final_rank: 9

code_snippet: #include <queue>
#include <cstdio>
#include <vector>
using namespace std;

#define PB push_back
const int N = 405;

int n, m;
int l[N], r[N];

int solve1() {
	vector<int> G[N];
	for (int i = 1; i <= n; ++i) {
		G[l[i]].PB(r[i]);
	}
	int ans = 0;
	priority_queue<int> q;
	for (int i = 1; i < N; ++i) {
		for (int j = 0; j < G[i].size(); ++j) {
			q.push(-G[i][j]);
		}
		while (!q.empty()) {
			int x = -q.top();
			if (x < i) {
				q.pop();
			}
			else break;
		}
		if (!q.empty()) {
			q.pop();
			ans++;
		}
	}
	return ans;
}

int vis1[N], vis2[N];

struct MCMF {
    const static int N = 1e4 + 5;
    const static int M = 1e6 + 5;
    const static int inf = 0x3f3f3f3f;

    int U[M], V[M], Cap[M], Cost[M], nxt[M];
    int NE, vs, vt, NV;
    int head[N], dist[N], pp[N], Q[N];
    bool vis[N];

    void init() {
        NE=0;
        for (int i = 0; i < NV; ++i)
        head[i] = -1;
    }

    void add(int u,int v,int cap,int cost) {
        U[NE] = u; V[NE] = v; Cap[NE] = cap; Cost[NE] =cost; nxt[NE] = head[u]; head[u] = NE++;
        U[NE] = v; V[NE] = u; Cap[NE] = 0; Cost[NE] = -cost; nxt[NE] = head[v]; head[v] = NE++;
    }

    bool SPFA() {
        int i, u, v, l = 0, r = 1;
        for (i = 0; i < NV; ++i) vis[i] = 0, pp[i] = -1, dist[i] = inf; // dist[i] = -1
        vis[vs] = 1; dist[vs] = 0;
        Q[0] = vs;
        while (l != r) {
            u = Q[l++]; vis[u] = 0;
            if (l == N) l = 0;
            for (i = head[u]; i!=-1; i = nxt[i]) {
                v = V[i];
                if (Cap[i] && dist[v] > dist[u] + Cost[i]) { // > ---> <
                    dist[v] = dist[u] + Cost[i];
                    pp[v] = i;
                    if (!vis[v]) {
                        Q[r++] = v;
                        vis[v] = 1;
                        if(r == N) r = 0;
                    }
                }
            }
        }
        if (dist[vt] == inf) return 0; //dist[vt] == -1
        return 1;
    }

    pair<int, int> solve() {
        int flow=0, i, minflow, mincost=0;
        while (SPFA()) {
            minflow = inf;
            for (i = pp[vt]; i != -1; i = pp[U[i]])
                minflow = min(Cap[i], minflow);
            flow += minflow;
            for (i = pp[vt]; i != -1; i = pp[U[i]])
                Cap[i] -= minflow, Cap[i ^ 1] += minflow;
            mincost += dist[vt] * minflow;
        }
        return pair<int, int>(flow,mincost);
    }

} sap;

int solve2() {
	sap.vs = 0; sap.vt = 800 + n + 1; sap.NV = sap.vt + 1; sap.init();
	for (int i = 1; i <= m; ++i) {
        sap.add(sap.vs, 800 + i, 1, 0);
        for (int j = l[i]; j <= r[i]; ++j)
            sap.add(800 + i, j, 1, 0);
    }
    for (int i = m + 1; i <= n; ++i) {
        sap.add(800 + i, sap.vt, 1, 0);
        for (int j = l[i];j <= r[i]; ++j)
            sap.add(j + 400, 800 + i, 1, 0);
    }
    for (int i = 1; i <= 400; ++i)
        sap.add(i, i + 400, 1, 1);
	return sap.solve().second;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d%d", &l[i], &r[i]);
	}
	printf("%d\n%d\n", solve1(), solve2());
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4740
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int N = 9999;
const int M = 1e5 + 5;
struct Dinic{
    struct Edge{
        int from,to,cap,flow,nxt;
        Edge(){}
        Edge(int u,int v,int c,int f,int n):
            from(u),to(v),cap(c),flow(f),nxt(n){}
    }edges[M];
    int n, s, t, E, head[N];
    bool vis[N]; //use when bfs
    int d[N],cur[N];//dist,now edge,use in dfs
    inline void AddEdge(int f,int t,int c){
        edges[++E] = Edge(f,t,c,0,head[f]);
        head[f] = E;
        edges[++E] = Edge(t,f,0,0,head[t]);
        head[t] = E;
    }
    inline void Init(int n,int s,int t){
        this -> n = n ; E = -1;
        this -> s = s ; head[s] = -1;
        this -> t = t ; head[t] = -1;
        for (int i=0;i<=n;i++) head[i] = -1;
    }

    inline bool BFS(){
        memset(vis,0,sizeof(vis));
        queue<int >Q;
        d[s] = 0; vis[s] = 1;
        for (Q.push(s);!Q.empty();){
            int x = Q.front(); Q.pop();
            for (int nxt,i = head[x];i!=-1;i = nxt){
                Edge &e = edges[i]; nxt = e.nxt;
                if (vis[e.to]||e.cap<=e.flow)continue;
                vis[e.to]=1;
                d[e.to]=d[x]+1;
                Q.push(e.to);
            }
        }
        return vis[t];
    }
    inline int DFS(const int& x,int a){
        if (x==t||a==0){return a;}
        int flow = 0, f, nxt;
        for (int& i=cur[x];i!=-1;i=nxt){
            Edge& e = edges[i]; nxt = e.nxt;
            if (d[x]+1!=d[e.to])continue;
            f = DFS(e.to,min(a,e.cap-e.flow));
            if (f <= 0)continue;
            e.flow += f;
            edges[i^1].flow-=f;  // 反向边
            flow+=f; a-=f;
            if (!a) break;
        }
        return flow;
    }
    inline int maxFlow(){return maxFlow(s,t);}
    inline int maxFlow(int s, int t){
        int flow = 0;
        for (; BFS(); ){
            for (int i = 0;i <= n; i++) cur[i] = head[i];
            flow += DFS(s,INF) ;
        }
        return flow;
    }
} g1, g2 ;
int main(){
    int n, k;
    cin >> n >> k;
    g1.Init(n + 402, 0, n + 401);
    g2.Init(n + 400 + 402, 0, n + 400 + 401);
    for (int i = 1; i <= k; i++){
        int x, y;
        cin >> x >> y;
        g1.AddEdge(0, i, 1);
        g2.AddEdge(0, i, 1);
        for (int j = x; j <= y; j++){
            g1.AddEdge(i, n + j, 1);
            g2.AddEdge(i, n + j, 1);
        }
    }
    for (int i = k + 1; i <= n; i++){
        int x, y;
        cin >> x >> y;
        g1.AddEdge(0, i, 1);
        g2.AddEdge(i, n + 400 + 401, 1);
        for (int j = x; j <= y; j++){
            g1.AddEdge(i, n + j, 1);
            g2.AddEdge(n + 400 + j, i, 1);
        }
    }
    for (int i = 1; i <= 400; i++){
        g1.AddEdge(n + i, n + 401, 1);
        g2.AddEdge(n + i, n + 400 + i, 1);
    }
    cout << g1.maxFlow() << endl << g2.maxFlow() << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 6944
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

struct Dinic{
  const Int INF=1<<28;
  
  struct edge {
    Int to,cap,rev;
    edge(){}
    edge(Int to,Int cap,Int rev):to(to),cap(cap),rev(rev){}
  };

  Int n;
  vector<vector<edge> > G;
  vector<map<Int,Int> > M;
  vector<Int> level,iter;

  Dinic(){}
  Dinic(Int sz):n(sz),G(n),M(n),level(n),iter(n){}
  
  void add_edge(Int from,Int to,Int cap){
    M[from][to]=G[from].size();
    M[to][from]=G[to].size();
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    //G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }
  
  void bfs(Int s){
    fill(level.begin(),level.end(),-1);
    queue<Int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
      Int v=que.front();que.pop();
      for(Int i=0;i<(Int)G[v].size();i++){
	edge &e = G[v][i];
	if(e.cap>0&&level[e.to]<0){
	  level[e.to]=level[v]+1;
	  que.push(e.to);
	}
      }
    }
  }
  
  Int dfs(Int v,Int t,Int f){
    if(v==t) return f;
    for(Int &i=iter[v];i<(Int)G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.to]){
	Int d = dfs(e.to,t,min(f,e.cap));
	if(d>0){
	  e.cap-=d;
	  G[e.to][e.rev].cap+=d;
	  return d;
	}
      }
    }
    return 0;
  }
  
  Int flow(Int s,Int t,Int lim){
    Int fl=0;
    for(;;){
      bfs(s);
      if(level[t]<0||lim==0) return fl;
      fill(iter.begin(),iter.end(),0);
      Int f;
      while((f=dfs(s,t,lim))>0){
	fl+=f;
	lim-=f;
      }
    }
  }

  Int flow(Int s,Int t){
    return flow(s,t,INF);
  }

  //cap==1 only
  bool back_edge(Int s,Int t,Int from, Int to){
    for(Int i=0;i<(Int)G[from].size();i++) {
      edge& e=G[from][i];
      if(e.to==to) {
	if(e.cap==0&&flow(from,to,1)==0) {
	  flow(from,s,1);
	  flow(t,to,1);
	  return 1;
	}
      }
    }
    return 0;
  }
};


template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
signed main(){
  Int n,m;
  cin>>n>>m;
  int d = 404;
  vector<Int> s(n),t(n);
  for(Int i=0;i<n;i++) cin>>s[i]>>t[i];  
  
  Int V=n+d*2;
  Int S=V++;
  Int T=V++;
  Dinic f(V);
  
  for(Int i=0;i<d;i++)
    f.add_edge(n+i,n+d+i,1);
  
  for(Int i=0;i<n;i++){
    s[i]--;
    if(i<m){
      f.add_edge(S,i,1);
      for(Int k=s[i];k<t[i];k++)
	f.add_edge(i,n+k,1);
    }else{
      for(Int k=s[i];k<t[i];k++)
	f.add_edge(n+d+k,i,1);
      f.add_edge(i,T,1);
    }
  }

  priority_queue<Int,vector<Int>, greater<Int> > pq;
  vector<queue<Int> > q(d); 
  for(Int i=0;i<n;i++) q[s[i]].emplace(t[i]);

  Int ans=0;
  for(Int i=0;i<d;i++){
    while(!q[i].empty()) pq.emplace(q[i].front()),q[i].pop();
    while(!pq.empty()&&pq.top()<=i) pq.pop();
    if(pq.empty()) continue;    
    ans++;pq.pop();
  }
  
  cout<<ans<<endl;
  cout<<f.flow(S,T)<<endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 12464
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

struct Dinic{
  const Int INF=1<<28;
  
  struct edge {
    Int to,cap,rev;
    edge(){}
    edge(Int to,Int cap,Int rev):to(to),cap(cap),rev(rev){}
  };

  Int n;
  vector<vector<edge> > G;
  vector<map<Int,Int> > M;
  vector<Int> level,iter;

  Dinic(){}
  Dinic(Int sz):n(sz),G(n),M(n),level(n),iter(n){}
  
  void add_edge(Int from,Int to,Int cap){
    M[from][to]=G[from].size();
    M[to][from]=G[to].size();
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    //G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }
  
  void bfs(Int s){
    fill(level.begin(),level.end(),-1);
    queue<Int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
      Int v=que.front();que.pop();
      for(Int i=0;i<(Int)G[v].size();i++){
	edge &e = G[v][i];
	if(e.cap>0&&level[e.to]<0){
	  level[e.to]=level[v]+1;
	  que.push(e.to);
	}
      }
    }
  }
  
  Int dfs(Int v,Int t,Int f){
    if(v==t) return f;
    for(Int &i=iter[v];i<(Int)G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.to]){
	Int d = dfs(e.to,t,min(f,e.cap));
	if(d>0){
	  e.cap-=d;
	  G[e.to][e.rev].cap+=d;
	  return d;
	}
      }
    }
    return 0;
  }
  
  Int flow(Int s,Int t,Int lim){
    Int fl=0;
    for(;;){
      bfs(s);
      if(level[t]<0||lim==0) return fl;
      fill(iter.begin(),iter.end(),0);
      Int f;
      while((f=dfs(s,t,lim))>0){
	fl+=f;
	lim-=f;
      }
    }
  }

  Int flow(Int s,Int t){
    return flow(s,t,INF);
  }

  //cap==1 only
  bool back_edge(Int s,Int t,Int from, Int to){
    for(Int i=0;i<(Int)G[from].size();i++) {
      edge& e=G[from][i];
      if(e.to==to) {
	if(e.cap==0&&flow(from,to,1)==0) {
	  flow(from,s,1);
	  flow(t,to,1);
	  return 1;
	}
      }
    }
    return 0;
  }
};


template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
signed main(){
  Int n,m;
  cin>>n>>m;
  vector<Int> s(n),t(n);
  for(Int i=0;i<n;i++) cin>>s[i]>>t[i];  
  
  Int V=n*3;
  Int S=V++;
  Int T=V++;
  Dinic f(V);
  
  for(Int i=0;i<n;i++){
    f.add_edge(n+i,n*2+i,1);
    s[i]--;chmin(t[i],n);
    //cout<<s[i]<<":"<<t[i]<<endl;
    if(i<m){
      f.add_edge(S,i,1);
      for(Int k=s[i];k<t[i];k++)
	f.add_edge(i,n+k,1);
    }else{
      f.add_edge(i,T,1);      
      for(Int k=s[i];k<t[i];k++)
	f.add_edge(n*2+k,i,1);
    }
  }

  priority_queue<Int,vector<Int>, greater<Int> > pq;
  vector<queue<Int> > q(404); 
  for(Int i=0;i<n;i++) q[s[i]].emplace(t[i]);

  Int ans=0;
  for(Int i=0;i<n;i++){
    while(!q[i].empty()) pq.emplace(q[i].front()),q[i].pop();
    while(!pq.empty()&&pq.top()<=i) pq.pop();
    if(pq.empty()) continue;    
    ans++;pq.pop();
  }
  
  cout<<ans<<endl;
  cout<<f.flow(S,T)<<endl;
  return 0;
}
accuracy: 0.036585365853658534
time_ms: 10
memory_kb: 12372
final_rank: 14

code_snippet: #include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int n, m, res = 1e9;
struct point {
	int b, e, ck;
	bool operator<(const point &p)const {
		return b < p.b;
	}
}w[410];
int D1[410][410], D2[410][410];
int main() {
	int i, RM = 0, j, k, MX = 0;
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++) {
		scanf("%d%d", &w[i].b, &w[i].e);
		if (i <= m)w[i].ck = 1;
		else w[i].ck = 2;
		MX = max(MX, w[i].e);
	}
	sort(w + 1, w + n + 1);
	priority_queue<int>PQ;
	int pv = 1;
	for (i = 1; i <= MX; i++) {
		while (pv <= n && w[pv].b == i) {
			PQ.push(-w[pv].e);
			pv++;
		}
		while (!PQ.empty() && -PQ.top() < i)PQ.pop();
		if (!PQ.empty())RM++, PQ.pop();
	}
	printf("%d\n", RM);
	for (i = 0; i <= MX; i++)for (j = 0; j <= MX; j++)D1[i][j] = 1e9, D2[i][j] = 1e9;
	D1[0][0] = D2[0][0] = 0;
	for (i = 0; i <= MX; i++) {
		for (j = 0; j <= i; j++) {
			if (D1[i][j] > 1e8 && D2[i][j] > 1e8)continue;
			int pv = 1;
			while (pv <= n && w[pv].b <= j)pv++;
			priority_queue<int>PQ2, PQ1;
			for (k = j + 1; k <= i; k++) {
				while (pv <= n && w[pv].b == k) {
					if(w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
			}
			int r2 = D1[i][j], r1 = D2[i][j];
			for (k = i + 1; k <= MX; k++){
				while (pv <= n && w[pv].b == k) {
					if (w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
				while (!PQ2.empty() && -PQ2.top() < k)PQ2.pop();
				while (!PQ1.empty() && -PQ1.top() < k)PQ1.pop();
				if (!PQ2.empty()) {
					PQ2.pop();
					r2++;
				}
				if(PQ2.empty())D2[k][i] = min(D2[k][i], r2);
				if (!PQ1.empty()) {
					PQ1.pop();
					r1++;
				}
				if (PQ1.empty())D1[k][i] = min(D1[k][i], r1);
				if (k == MX)res = min(res, min(r1,r2));
			}
		}
	}
	printf("%d\n", res);
}
accuracy: 1
time_ms: 430
memory_kb: 4112
final_rank: 8

code_snippet: #include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int n, m, res = 1e9;
struct point {
	int b, e, ck;
	bool operator<(const point &p)const {
		return b < p.b;
	}
}w[410];
int D1[410][410], D2[410][410];
int main() {
	int i, RM = 0, j, k, MX = 0;
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++) {
		scanf("%d%d", &w[i].b, &w[i].e);
		if (i <= m)w[i].ck = 1;
		else w[i].ck = 2;
		MX = max(MX, w[i].e);
	}
	sort(w + 1, w + n + 1);
	priority_queue<int>PQ;
	int pv = 1;
	for (i = 1; i <= MX; i++) {
		while (pv <= n && w[pv].b == i) {
			PQ.push(-w[pv].e);
			pv++;
		}
		while (!PQ.empty() && -PQ.top() < i)PQ.pop();
		if (!PQ.empty())RM++, PQ.pop();
	}
	printf("%d\n", RM);
	for (i = 0; i <= MX; i++)for (j = 0; j <= MX; j++)D1[i][j] = 1e9, D2[i][j] = 1e9;
	D1[0][0] = D2[0][0] = 0;
	for (i = 0; i <= MX; i++) {
		for (j = 0; j <= i; j++) {
			if (D1[i][j] > 1e8 && D2[i][j] > 1e8)continue;
			int pv = 1;
			while (pv <= n && w[pv].b <= j)pv++;
			priority_queue<int>PQ2, PQ1;
			for (k = j + 1; k <= i; k++) {
				while (pv <= n && w[pv].b == k) {
					if(w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
			}
			int r2 = D1[i][j], r1 = D2[i][j];
			for (k = i + 1; k <= MX; k++){
				while (pv <= n && w[pv].b == k) {
					if (w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
				while (!PQ2.empty() && -PQ2.top() < k)PQ2.pop();
				while (!PQ1.empty() && -PQ1.top() < k)PQ1.pop();
				if (!PQ2.empty()) {
					PQ2.pop();
					r2++;
				}
				else D2[k][i] = min(D2[k][i], r2);
				if (!PQ1.empty()) {
					PQ1.pop();
					r1++;
				}
				else D1[k][i] = min(D1[k][i], r1);
				if (k == MX)res = min(res, min(r1,r2));
			}
		}
	}
	printf("%d\n", res);
}
accuracy: 0.45121951219512196
time_ms: 80
memory_kb: 4072
final_rank: 11

code_snippet: #include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int n, m, res = 1e9;
struct point {
	int b, e, ck;
	bool operator<(const point &p)const {
		return b < p.b;
	}
}w[410];
int D1[410][410], D2[410][410];
int main() {
	int i, RM = 0, j, k, MX = 0;
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++) {
		scanf("%d%d", &w[i].b, &w[i].e);
		if (i <= m)w[i].ck = 1;
		else w[i].ck = 2;
		MX = max(MX, w[i].e);
	}
	sort(w + 1, w + n + 1);
	priority_queue<int>PQ;
	int pv = 1;
	for (i = 1; i <= MX; i++) {
		while (pv <= n && w[pv].b == i) {
			PQ.push(-w[pv].e);
			pv++;
		}
		while (!PQ.empty() && -PQ.top() < i)PQ.pop();
		if (!PQ.empty())RM++, PQ.pop();
	}
	printf("%d\n", RM);
	for (i = 0; i <= n; i++)for (j = 0; j <= n; j++)D1[i][j] = 1e9, D2[i][j] = 1e9;
	D1[0][0] = D2[0][0] = 0;
	for (i = 0; i <= MX; i++) {
		for (j = 0; j <= i; j++) {
			if (D1[i][j] > 1e8 && D2[i][j] > 1e8)continue;
			int pv = 1;
			while (pv <= n && w[pv].b <= j)pv++;
			priority_queue<int>PQ2, PQ1;
			for (k = j + 1; k <= i; k++) {
				while (pv <= n && w[pv].b == k) {
					if(w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
			}
			int r2 = D1[i][j], r1 = D2[i][j];
			for (k = i + 1; k <= MX; k++){
				while (pv <= n && w[pv].b == k) {
					if (w[pv].ck == 2) PQ2.push(-w[pv].e);
					else PQ1.push(-w[pv].e);
					pv++;
				}
				while (!PQ2.empty() && -PQ2.top() < k)PQ2.pop();
				while (!PQ1.empty() && -PQ1.top() < k)PQ1.pop();
				if (!PQ2.empty()) {
					PQ2.pop();
					r2++;
				}
				else D2[k][i] = min(D2[k][i], r2);
				if (!PQ1.empty()) {
					PQ1.pop();
					r1++;
				}
				else D1[k][i] = min(D1[k][i], r1);
				if (k == MX)res = min(res, min(r1,r2));
			}
		}
	}
	printf("%d\n", res);
}
accuracy: 0.036585365853658534
time_ms: 70
memory_kb: 3932
final_rank: 12