#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
int best, n, num[MAXN], path[MAXN], G[MAXN][MAXN];
bool dfs(int *adj, int total, int cnt) {
  int t[MAXN];
  if (total == 0) return best < cnt ? best = cnt, true : false;
  for (int i = 0; i < total; i++) {
    if (cnt + (total - i) <= best) return false;
    if (cnt + num[adj[i]] <= best) return false;
    int k = 0;
    for (int j = i + 1; j < total; j++)
      if (G[adj[i]][adj[j]]) t[k++] = adj[j];
    if (dfs(t, k, cnt + 1)) return true;
  }
  return false;
}
int MaximumClique() {
  int adj[MAXN];
  best = 0;
  if (n <= 0) return 0;
  for (int i = n - 1; i >= 0; i--) {
    int k = 0;
    for (int j = i + 1; j < n; j++)
      if (G[i][j]) adj[k++] = j;
    dfs(adj, k, 1);
    num[i] = best;
  }
  return best;
}
int getId(string &s, map<string, int> &mp) {
  int m = mp.size();
  if (!mp.count(s)) mp[s] = m;
  return mp[s];
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int m;
  cin >> m >> n;
  memset(G, 0, sizeof(G));
  vector<vector<int>> A(n, vector<int>(n, 0));
  set<int> st;
  map<string, int> mp;
  while (m--) {
    int op;
    cin >> op;
    if (op == 1) {
      vector<int> res;
      for (auto &v : st) res.push_back(v);
      for (int i = 0; i < res.size(); i++)
        for (int j = 0; j < i; j++) A[res[i]][res[j]] = A[res[j]][res[i]] = 1;
      st.clear();
    } else if (op == 2) {
      string s;
      cin >> s;
      st.insert(getId(s, mp));
    }
  }
  vector<int> res;
  for (auto &v : st) res.push_back(v);
  for (int i = 0; i < res.size(); i++)
    for (int j = 0; j < i; j++) A[res[i]][res[j]] = A[res[j]][res[i]] = 1;
  st.clear();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i == j) continue;
      G[i][j] = !A[i][j];
    }
  }
  cout << MaximumClique() << '\n';
}
