Problem: Problem Statement

You are given a list of $N$ intervals. The $i$-th interval is $[l_i, r_i)$, which denotes a range of numbers greater than or equal to $l_i$ and strictly less than $r_i$. In this task, you consider the following two numbers:

* The minimum integer $x$ such that you can select $x$ intervals from the given $N$ intervals so that the union of the selected intervals is $[0, L)$.
* The minimum integer $y$ such that for all possible combinations of $y$ intervals from the given $N$ interval, it does cover $[0, L)$.



We ask you to write a program to compute these two numbers.

* * *

Input

The input consists of a single test case formatted as follows.

> $N$ $L$ $l_1$ $r_1$ $l_2$ $r_2$ $\vdots$ $l_N$ $r_N$

The first line contains two integers $N$ ($1 \leq N \leq 2 \times 10^5$) and $L$ ($1 \leq L \leq 10^{12}$), where $N$ is the number of intervals and $L$ is the length of range to be covered, respectively. The $i$-th of the following $N$ lines contains two integers $l_i$ and $r_i$ ($0 \leq l_i < r_i \leq L$), representing the range of the $i$-th interval $[l_i, r_i)$. You can assume that the union of all the $N$ intervals is $[0, L)$

Output

Output two integers $x$ and $y$ mentioned in the problem statement, separated by a single space, in a line.

Examples

Input| Output
---|---


3 3
0 2
1 3
1 2


|


2 3



2 4
0 4
0 4


|


1 1



5 4
0 2
2 4
0 3
1 3
3 4


|


2 4






Example

Input




Output

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
#define pb push_back
#define fi first
#define sec second
#define INF 1000000000
const int SIZE = 1<<20;
struct segtree{
	int seg[SIZE*2];
	segtree(){
		for(int i=0;i<SIZE*2;i++){
			seg[i] = INF;
		}
	}
	void update(int k,int x){
		k += SIZE-1;
		seg[k] = min(seg[k],x);
		while(k>0){
			k = (k-1)/2;
			seg[k] = min(seg[k*2+1],seg[k*2+2]);
		}
	}
	int query(int a,int b,int k,int l,int r){
		if(r<=a||b<=l)return INF;
		if(a<=l&&r<=b)return seg[k];
		int mid = (l+r)/2;
		return min(query(a,b,k*2+1,l,mid),query(a,b,k*2+2,mid,r));
	}
}seg;
bool comp(P a,P b){
	if(a.sec!=b.sec)return a.sec < b.sec;
	else return a.fi < b.fi;
}
int N;
ll L;
vector<ll> zip;
vector<P> vec;
int dp[400100];
int rui[400100];
int main(){
	cin >> N >> L;
	zip.pb(L);
	vec.resize(N);
	for(int i=0;i<N;i++){
		cin >> vec[i].fi >> vec[i].sec;
		zip.pb(vec[i].fi);
		zip.pb(vec[i].sec);
	}
	zip.pb(0ll);
	sort(zip.begin(),zip.end());
	zip.erase(unique(zip.begin(),zip.end()),zip.end());
	for(int i=0;i<N;i++){
		vec[i].fi = lower_bound(zip.begin(),zip.end(),vec[i].fi)-zip.begin();
		vec[i].sec = lower_bound(zip.begin(),zip.end(),vec[i].sec)-zip.begin();
		rui[vec[i].fi]++;
		rui[vec[i].sec]--;
	}
	sort(vec.begin(),vec.end(),comp);
	// for(int i=0;i<vec.size();i++){
	// 	cout << vec[i].fi << ' ' << vec[i].sec << endl;
	// }
	for(int i=1;i<=zip.size();i++){
		dp[i] = INF;
	}
	dp[0] = 0ll;
	seg.update(0,dp[0]);
	for(int i=0;i<vec.size();i++){
		int l = vec[i].fi;
		int r = vec[i].sec;
		dp[r] = min(dp[r],seg.query(l,r,0,0,SIZE)+1);
		seg.update(r,dp[r]);
	}
	for(int i=1;i<zip.size();i++){
		rui[i] += rui[i-1];
	}
	int mi = INF;
	for(int i=0;i+1<zip.size();i++){
		mi = min(mi,rui[i]);
	}
	cout << dp[zip.size()-1] << ' ' << N-mi+1 << endl;
	return 0;
}