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

using P = pair<int, int>;
constexpr int INF = 1000000000;
int N, M;


class segTree
{
    vector<int> data;
    vector<int> rangeadd;
    int N;
    void _update(int n)
    {
        data[n] = min(data[2*n+1] + rangeadd[2*n+1], data[2*n+2] + rangeadd[2*n+2]);
    }
public:
    segTree(vector<int> initial, int DEFAULT)
    {
        N = initial.size();
        int tmp = 1;
        while (tmp<(int)initial.size()) tmp*=2;
        tmp *= 2;
        data = vector<int>(tmp, DEFAULT);
        rangeadd = vector<int>(tmp, 0);
        for (int i=0; i<N; i++)
        {
            data[i + data.size()/2 - 1] = initial[i];
        }
        for (int i=data.size()/2-2; i>=0; i--) _update(i);
    }

    void _range_add(int begin, int end, int node, int l, int r, int val)
    {
        if (r <= begin || l >= end) return;
        if (begin<=l && end>=r)
        {
            rangeadd[node] += val;
        }
        else
        {
            _range_add(begin, end, 2 * node + 1, l, (l + r) / 2, val);
            _range_add(begin, end, 2 * node + 2, (l + r) / 2, r, val);
            _update(node);
        }
    }
    void range_add(int begin, int end, int val)
    {
        _range_add(begin, end, 0, 0, (int)data.size() / 2, val);
    }

    int _query_min(int begin, int end, int node, int l, int r)
    {
        if (r <= begin || l >= end) return INF;
        if (begin<=l && end>=r) return data[node] + rangeadd[node];

        int v_l = _query_min(begin, end, 2 * node + 1, l, (l + r) / 2);
        int v_r = _query_min(begin, end, 2 * node + 2, (l + r) / 2, r);
        return min(v_l, v_r) + rangeadd[node];
    }
    int min_(int begin, int end)
    {
        return _query_min(begin, end, 0, 0, (int)data.size() / 2);
    }
};


vector<P> range;
bool lessR(const P& pleft, const P& pright)
{
    if (pleft.second == pright.second) return pleft.first < pright.first;
    else return pleft.second < pright.second;
}

int main()
{
    cin >> N >> M;
    range.resize(N);
    for (auto &v : range) cin >> v.second >> v.first;

    sort(range.begin(), range.end(), lessR);
    vector<bool> isUsed(range.size(), false);
    int numUsed = 0;

    vector<int> tmp1(M+1);
    for (int i=1; i<=M; i++) tmp1[i] = i;
    segTree tree1(tmp1, INF);

    for (unsigned i=0; i<range.size(); i++)
    {
        // cout << range[i].first << " " << range[i].second << endl;
        int q = min(M + 1 - range[i].first, M);
        // cout << "candidate: " << q << " " << tree1.min_(q, M+1) << endl;
        if (tree1.min_(q, M+1) > 0)
        {
            // cout << "add" << endl;
            tree1.range_add(q, M+1, -1);
            isUsed[i] = true;
            numUsed++;
        }
    }

    int Mnew = M - numUsed;
    vector<int> tmp2(Mnew+1);
    for (int i=1; i<=Mnew; i++) tmp2[i] = i;
    segTree tree2(tmp2, INF);

    // cout << "Mnew=" << Mnew << endl;
    for (unsigned i=0; i<range.size(); i++)
    {
        if (isUsed[i]) continue;
        // cout << range[i].first << " " << range[i].second << endl;
        int q = min(range[i].second, Mnew);
        // cout << "2candidate: " << q << " " << tree2.min_(q, Mnew+1) << endl;
        if (tree2.min_(q, Mnew+1) > 0)
        {
            // cout << "add" << endl;
            tree2.range_add(q, Mnew+1, -1);
            numUsed++;
        }
    }
    cout << N - numUsed << endl;
    return 0;
}

Measured memory_bytes: 12400