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 <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

#define SIZE 400000
#define SIZE0 200000
#define INF 1000000000

typedef long long ll;

struct Segtree {
  int segn2;
  vector<int> data;

  Segtree(int n) {
    for(segn2=1; segn2<n; segn2*=2);
    data.assign(segn2*2, 1000000000);
  }

  int query(int a, int b, int l = 0, int r = -1, int k = 0) {
    if (r == -1) r = segn2;
    if (a <= l && r <= b) return data[k];
    if (r <= a || b <= l) return INF;
    return min(query(a, b, l, (l+r)/2, k*2+1), query(a, b, (l+r)/2, r, k*2+2));
  }

  void set(int k, int x) {
    k += segn2-1;
    data[k] = x;
    while(k > 0) {
      k = (k-1)/2;
      data[k] = min(data[k*2+1], data[k*2+2]);
    }
  }
};


int N;
ll L;
int M;
pair<ll,ll> p[SIZE0];

int memo[SIZE];
int solve1() {
  Segtree seg(M+1);

  seg.set(0, 0);

  for(int i=0; i<M; i++) {
    memo[i] = INF;
  }
  memo[0] = 0;

  for(int i=0; i<N; i++) {
    int l = p[i].first;
    int r = p[i].second;

    int v = seg.query(l, r);
    memo[r] = min(memo[r], v+1);
    seg.set(r, memo[r]);

  }

  return seg.query(M-1, M);
}

int sum[SIZE];
int solve2() {

  for(int i=0; i<N; i++) {
    sum[p[i].first]++;
    sum[p[i].second]--;
  }

  int ans = 1e9;

  for(int i=0; i<M-1; i++) {
    sum[i+1] += sum[i];
    ans = min(ans, sum[i]);
  }

  return N - ans + 1;
}

int main(){
  vector<ll> vec;
  map<ll, int> dic;

  scanf("%d%lld", &N, &L);

  for(int i=0; i<N; i++) {
    ll l, r;
    scanf("%lld%lld", &l, &r);

    p[i] = {l, r};
    vec.push_back(l);
    vec.push_back(r);
  }

  sort(vec.begin(), vec.end());
  vec.erase(unique(vec.begin(), vec.end()), vec.end());

  M = vec.size();

  for(int i=0; i<vec.size(); i++) {
    dic[vec[i]] = i;
  }

  sort(p, p+N);

  for(int i=0; i<N; i++) {
    p[i].first = dic[p[i].first];
    p[i].second = dic[p[i].second];
  }


  int ans1 = solve1();
  int ans2 = solve2();

  printf("%d %d\n", ans1, ans2);

  return 0;
}