/*
* Problem :: 3020 / 개똥벌레
*
* Kind :: Binary Search
*
* Insight
* - 일단 석순은 석순끼리, 종유석은 종유석끼리 나누자
* + 석순 기준 1번째 구간으로 개똥벌레가 날아가면,
* 크기 1 이상인 석순은 모두 파괴된다
* 석순 기준 2번째 구간으로 개똥벌레가 날아가면,
* 크기 2 이상인 석순은 모두 파괴된다
* # 파괴되는 석순을 일일이 세면... O(NH) > O(10^8) 이라서 제한시간 내에 풀 수 없다
* 크기 n 이상의 석순의 개수를 빨리 알 수 있는 방법은 없을까?
* -> 오름차순으로 정렬해놓고 lower_bound 쓰면
* 첫번째로 만나는 크기 n 이상인 석순의 위치를 찾을 수 있다! <- log(N)
* Vector 라면 end - lower_bound 로 쉽게 크기 n 이상의 석순의 개수를 알 수 있다!
*
* Point
* - 종유석은 거꾸로 매달려 있으므로
* + 종유석 기준 1번째 구간으로 개똥벌레가 날아가면,
* 크기 H 이상인 종유석은 모두 파괴된다
* 종유석 기준 2번째 구간으로 개똥벌레가 날아가면,
* 크기 H-1 이상인 종유석은 모두 파괴된다
* # 오름차순으로 정렬해놓고 lower_bound 쓰는 것은 같되
* i번째 구간으로 개똥벌레가 날아가면
* 크기 H-i+1 이상인 종유석이 파괴되는 것을 염두에 두자
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N, H;
cin >> N >> H;
vector<int> U(N/2), D(N/2); /* 차례로 석순의 크기와 종유석의 크기를 저장하는 Vector */
for (int i=0; i<N/2; i++)
cin >> U[i] >> D[i];
// Process
sort(U.begin(), U.end()); /* 오름차순으로 석순 정렬 */
sort(D.begin(), D.end()); /* 오름차순으로 종유석 정렬 */
int ans1 = -1, ans2 = 0; /* ans1 = 파괴해야 하는 장애물의 최솟값,
* ans2 = 그러한 구간의 수 */
for (int h=1; h<=H; h++) {
/* 높이 h 일 때 */
/* 파괴되는 석순의 개수 */
int u_cnt = U.end() - lower_bound(U.begin(), U.end(), h);
/* 파괴되는 종유석의 개수 */
int d_cnt = D.end() - lower_bound(D.begin(), D.end(), H-h+1);
int cnt = u_cnt + d_cnt; /* 총 파괴되는 장애물의 개수 */
if (ans1 == -1 || ans1 > cnt) {
ans1 = cnt;
ans2 = 1;
} else if (ans1 == cnt) {
ans2++;
}
}
// Control : Output
cout << ans1 << ' ' << ans2 << endl;
}
// Helper Functions
/* None */