#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200050;
const int MAXS = 50;
struct Hash {
  int P = 1777771, MOD[2], PI[2];
  vector<int> h[2], pi[2];
  Hash(const string &s = "") {
    MOD[0] = 999727999;
    MOD[1] = 1070777777;
    PI[0] = 325255434;
    PI[1] = 10018302;
    for (int k = (0); k < (int)(2); k++)
      h[k].resize(((int)s.size()) + 1), pi[k].resize(((int)s.size()) + 1);
    for (int k = (0); k < (int)(2); k++) {
      h[k][0] = 0;
      pi[k][0] = 1;
      long long p = 1;
      for (int i = (1); i < (int)(((int)s.size()) + 1); i++) {
        h[k][i] = (h[k][i - 1] + p * s[i - 1]) % MOD[k];
        pi[k][i] = (1LL * pi[k][i - 1] * PI[k]) % MOD[k];
        p = (p * P) % MOD[k];
      }
    }
  }
  long long get(int s, int e) {
    long long r[2];
    for (int k = (0); k < (int)(2); k++) {
      r[k] = (h[k][e] - h[k][s] + MOD[k]) % MOD[k];
      r[k] = (1LL * r[k] * pi[k][s]) % MOD[k];
    }
    return (r[0] << 32) | r[1];
  }
};
int n, m, t[MAXN], w[MAXN];
map<string, int> M;
string name[MAXN];
char ss[MAXS];
long long G[MAXS], mx;
void getstring(string &s) {
  scanf(" %s", ss);
  s = ss;
}
long long pop(long long v) {
  if (v == 0) return 0;
  return __builtin_popcountll(v);
}
void Bron(long long R, long long P, long long X) {
  if (P == 0 && X == 0) {
    mx = max(mx, pop(R));
    return;
  }
  int u;
  long long PX = P | X;
  for (int i = (0); i < (int)(m); i++)
    if (PX & (1LL << i)) {
      u = i;
      break;
    }
  for (int i = (0); i < (int)(m); i++) {
    if ((P & ~G[u]) & (1LL << i)) {
      Bron(R | (1LL << i), P & G[i], X & G[i]);
      P = P ^ (1LL << i);
      X = X | (1LL << i);
    }
  }
}
int main() {
  while (scanf("%d %d", &n, &m) >= 1) {
    memset(G, 0, sizeof(G));
    for (int i = (0); i < (int)(m); i++) {
      for (int j = (0); j < (int)(m); j++) {
        G[i] ^= (1LL << j);
      }
    }
    for (int i = (0); i < (int)(m); i++) {
      G[i] ^= (1LL << i);
    }
    for (int i = (0); i < (int)(n); i++) {
      scanf("%d", &t[i]);
      if (t[i] == 2) {
        getstring(name[i]);
        M[name[i]];
      }
    }
    int sz = 0;
    for (auto &it : M) {
      it.second = sz++;
    }
    for (int i = (0); i < (int)(n); i++) {
      if (t[i] == 2) {
        w[i] = M[name[i]];
      }
    }
    set<int> S;
    for (int i = n - 1; i >= 0; i--) {
      if (t[i] == 2) {
        S.insert(w[i]);
      } else {
        vector<int> V(S.begin(), S.end());
        for (int i = (0); i < (int)(((int)V.size())); i++) {
          int v = V[i];
          for (int j = (i + 1); j < (int)(((int)V.size())); j++) {
            int w = V[j];
            if (G[v] & (1LL << w)) G[v] ^= (1LL << w);
            if (G[w] & (1LL << v)) G[w] ^= (1LL << v);
          }
        }
        S.clear();
      }
    }
    Bron(0, (1LL << m) - 1, 0);
    printf("%lld\n", mx);
  }
  return 0;
}
