```go
package main
import (
"bufio"
"fmt"
"math/bits"
"os"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanLines)
scanner.Scan()
line := scanner.Text()
var n, m int
fmt.Sscanf(line, "%d %d", &n, &m)
events := make([]struct {
typ int
name string
}, n)
nameToIdx := make(map[string]int)
for i := 0; i < n; i++ {
scanner.Scan()
line = strings.TrimSpace(scanner.Text())
if line[0] == '1' {
events[i].typ = 1
} else {
events[i].typ = 2
parts := strings.Split(line, " ")
name := parts[1]
events[i].name = name
if _, ok := nameToIdx[name]; !ok {
nameToIdx[name] = len(nameToIdx)
}
}
}
friendSegs := make([]map[int]bool, m)
for i := range friendSegs {
friendSegs[i] = make(map[int]bool)
}
curSeg := -1
for _, ev := range events {
if ev.typ == 1 {
curSeg++
} else {
idx := nameToIdx[ev.name]
friendSegs[idx][curSeg] = true
}
}
conflict := make([]uint64, m)
for i := 0; i < m; i++ {
for j := i + 1; j < m; j++ {
intersect := false
if len(friendSegs[i]) > len(friendSegs[j]) {
for seg := range friendSegs[j] {
if friendSegs[i][seg] {
intersect = true
break
}
}
} else {
for seg := range friendSegs[i] {
if friendSegs[j][seg] {
intersect = true
break
}
}
}
if intersect {
conflict[i] |= 1 << uint(j)
conflict[j] |= 1 << uint(i)
}
}
}
m1 := m / 2
m2 := m - m1
sizeA := 1 << m1
dp := make([]int, sizeA)
for mask := 1; mask < sizeA; mask++ {
lsb := mask & -mask
v := bits.TrailingZeros(uint(lsb))
maskWithoutV := mask ^ lsb
best := dp[maskWithoutV]
neighbors := int(conflict[v] & uint64(mask))
maskWithoutNeighbors := maskWithoutV & ^neighbors
cand := 1 + dp[maskWithoutNeighbors]
if cand > best {
best = cand
}
dp[mask] = best
}
fullA := sizeA - 1
ans := 0
sizeB := 1 << m2
for maskB := 0; maskB < sizeB; maskB++ {
valid := true
forbiddenA := 0
temp := maskB
for temp > 0 {
lsb := temp & -temp
i := bits.TrailingZeros(uint(lsb))
v := m1 + i
conflictB := int((conflict[v] >> uint(m1)) & uint64(sizeB-1))
if conflictB&maskB != 0 {
valid = false
break
}
forbiddenA |= int(conflict[v] & uint64(fullA))
temp -= lsb
}
if !valid {
continue
}
allowedA := fullA & ^forbiddenA
total := bits.OnesCount(uint(maskB)) + dp[allowedA]
if total > ans {
ans = total
}
}
fmt.Println(ans)
}
```