package main
import (
"bufio"
"fmt"
"io"
"os"
"sort"
)
const negInf int64 = -1 << 60
type Fenwick struct {
t []int64
}
func NewFenwick(n int) *Fenwick {
return &Fenwick{t: make([]int64, n+1)}
}
func (f *Fenwick) Add(i int, v int64) {
for i++; i < len(f.t); i += i & -i {
f.t[i] += v
}
}
func (f *Fenwick) Sum(i int) int64 {
var res int64
for i++; i > 0; i -= i & -i {
res += f.t[i]
}
return res
}
type SegTree struct {
n int
mx []int64
lz []int64
}
func NewSegTree(n int) *SegTree {
s := &SegTree{
n: n,
mx: make([]int64, 4*n+5),
lz: make([]int64, 4*n+5),
}
for i := range s.mx {
s.mx[i] = negInf
}
return s
}
func max64(a, b int64) int64 {
if a > b {
return a
}
return b
}
func (s *SegTree) push(v int) {
if s.lz[v] != 0 {
add := s.lz[v]
lc, rc := v<<1, v<<1|1
s.mx[lc] += add
s.lz[lc] += add
s.mx[rc] += add
s.lz[rc] += add
s.lz[v] = 0
}
}
func (s *SegTree) RangeAdd(l, r int, val int64) {
if l > r {
return
}
s.rangeAdd(1, 0, s.n-1, l, r, val)
}
func (s *SegTree) rangeAdd(v, tl, tr, l, r int, val int64) {
if l <= tl && tr <= r {
s.mx[v] += val
s.lz[v] += val
return
}
s.push(v)
tm := (tl + tr) >> 1
if l <= tm {
s.rangeAdd(v<<1, tl, tm, l, r, val)
}
if r > tm {
s.rangeAdd(v<<1|1, tm+1, tr, l, r, val)
}
s.mx[v] = max64(s.mx[v<<1], s.mx[v<<1|1])
}
func (s *SegTree) Query(l, r int) int64 {
if l > r {
return negInf
}
return s.query(1, 0, s.n-1, l, r)
}
func (s *SegTree) query(v, tl, tr, l, r int) int64 {
if l <= tl && tr <= r {
return s.mx[v]
}
s.push(v)
tm := (tl + tr) >> 1
res := negInf
if l <= tm {
res = max64(res, s.query(v<<1, tl, tm, l, r))
}
if r > tm {
res = max64(res, s.query(v<<1|1, tm+1, tr, l, r))
}
return res
}
func (s *SegTree) PointSet(pos int, val int64) {
s.pointSet(1, 0, s.n-1, pos, val)
}
func (s *SegTree) pointSet(v, tl, tr, pos int, val int64) {
if tl == tr {
s.mx[v] = val
s.lz[v] = 0
return
}
s.push(v)
tm := (tl + tr) >> 1
if pos <= tm {
s.pointSet(v<<1, tl, tm, pos, val)
} else {
s.pointSet(v<<1|1, tm+1, tr, pos, val)
}
s.mx[v] = max64(s.mx[v<<1], s.mx[v<<1|1])
}
func upperBound(a []int, x int) int {
l, r := 0, len(a)
for l < r {
m := (l + r) >> 1
if a[m] <= x {
l = m + 1
} else {
r = m
}
}
return l
}
type Item struct {
s int
idxA int
}
func main() {
data, _ := io.ReadAll(os.Stdin)
p := 0
nextInt := func() int {
for p < len(data) && (data[p] < '0' || data[p] > '9') {
p++
}
v := 0
for p < len(data) && data[p] >= '0' && data[p] <= '9' {
v = v*10 + int(data[p]-'0')
p++
}
return v
}
n := nextInt()
d := nextInt()
sArr := make([]int, n)
aArr := make([]int, n)
vals := make([]int, 0, n+1)
vals = append(vals, d)
for i := 0; i < n; i++ {
s := nextInt()
a := nextInt()
sArr[i] = s
aArr[i] = a
if a > d {
vals = append(vals, a)
}
}
sort.Ints(vals)
levels := vals[:0]
for _, v := range vals {
if len(levels) == 0 || levels[len(levels)-1] != v {
levels = append(levels, v)
}
}
m := len(levels)
idxMap := make(map[int]int, m)
for i, v := range levels {
idxMap[v] = i
}
maxS := make([]int, m)
maxLow := make([]int, m)
for i := 0; i < m; i++ {
maxS[i] = -1
maxLow[i] = -1
}
active := make([]Item, 0, n)
bit := NewFenwick(m)
for i := 0; i < n; i++ {
s := sArr[i]
a := aArr[i]
idxA := 0
if a > d {
idxA = idxMap[a]
if s > maxS[idxA] {
maxS[idxA] = s
}
if s < a && s > maxLow[idxA] {
maxLow[idxA] = s
}
}
if s >= d {
active = append(active, Item{s: s, idxA: idxA})
bit.Add(idxA, 1)
}
}
sort.Slice(active, func(i, j int) bool {
return active[i].s < active[j].s
})
seg := NewSegTree(m)
seg.PointSet(0, 0)
ans := bit.Sum(0)
ptr := 0
for qIdx := 1; qIdx < m; qIdx++ {
q := levels[qIdx]
for ptr < len(active) && active[ptr].s < q {
bit.Add(active[ptr].idxA, -1)
seg.RangeAdd(active[ptr].idxA, m-1, 1)
ptr++
}
cover := bit.Sum(qIdx)
best := negInf
if maxS[qIdx] >= d {
lim := upperBound(levels, maxS[qIdx]) - 1
if lim > qIdx-1 {
lim = qIdx - 1
}
if lim >= 0 {
v := seg.Query(0, lim)
if v > best {
best = v
}
}
}
if maxLow[qIdx] >= d {
lim := upperBound(levels, maxLow[qIdx]) - 1
if lim > qIdx-1 {
lim = qIdx - 1
}
if lim >= 0 {
v := seg.Query(0, lim) + 1
if v > best {
best = v
}
}
}
if best != negInf {
dp := cover + best
if dp > ans {
ans = dp
}
seg.PointSet(qIdx, dp-cover)
} else {
seg.PointSet(qIdx, negInf)
}
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
fmt.Fprint(out, ans)
out.Flush()
}