Problem:
Score : 300 points

Problem Statement

You drew lottery N times. In the i-th draw, you got an item of the kind represented by a string S_i.

How many kinds of items did you get?

Constraints

1 \leq N \leq 2\times 10^5

S_i consists of lowercase English letters and has a length between 1 and 10 (inclusive).

Input

Input is given from Standard Input in the following format:

N
S_1
:
S_N

Output

Print the number of kinds of items you got.

Sample Input 1

3
apple
orange
apple

Sample Output 1

2

You got two kinds of items: apple and orange.

Sample Input 2

5
grape
grape
grape
grape
grape

Sample Output 2

1

Sample Input 3

4
aaaa
a
aaa
aa

Sample Output 3

4

Solution in C (GCC 9.2.1) (judge verdict: Accepted)

#include <stdio.h>

#define tsort long
#define smaxn 200000 //最大要素数
#define smxbit 50 //要素のうち最大の数値のビット数
#define snobit 17 //1-smxbitの間で調整、増やせば速いがメモリを消費する
#define rev 1     //0で昇順、1で降順
#define snosc (1<<(snobit+1))

int sort(tsort *vlist,int *plist,int n){
  int h,i,j,k,l,m,s,p,qlist[smaxn],c[snosc][3],ss;
#if rev
  ss=snosc-1;
#else
  ss=0;
#endif
  tsort vj,vk,mx[snosc];
  for(i=0;i<snosc;i++){
    c[i][0]=-1;
    c[i][1]=-1;
  }
  for(i=0;i<n;i++){
    l=(int)(vlist[i]>>(smxbit-snobit))&(snosc-1)^(1<<snobit);
    if(c[l][0]==-1){
      c[l][0]=i;
      c[l][2]=i;
      mx[l]=vlist[i];
    }else{
      qlist[c[l][1]]=i;
#if rev
      if(vlist[i]<mx[l]){
#else
      if(vlist[i]>mx[l]){
#endif
        c[l][2]=i;
        mx[l]=vlist[i];
      }
    }
    c[l][1]=i;
    plist[i]=-1;
  }
#if rev
  for(h=snosc-1;h>=0;h--){
#else
  for(h=0;h<snosc;h++){
#endif
    s=c[h][0];
    if(s==-1){
#if rev
      if(h==ss) ss--;
      if(h!=snosc-1) c[h][1]=c[h+1][1];
#else
      if(h==ss) ss++;
      if(h!=0) c[h][1]=c[h-1][1];
#endif
      continue;
    }
    qlist[c[h][1]]=-1;
    while(qlist[s]!=-1){
      i=s;
      p=-1;
      while(i!=-1){
        j=i;
        k=qlist[j];
        if(k==-1) break;
        i=qlist[k];
#if rev
        if(vlist[j]<vlist[k])
#else
        if(vlist[j]>vlist[k])
#endif
        {
          if(p==-1){
            s=k;
          }else{
            qlist[p]=k;
          }
          l=j;
          j=k;
          k=l;
        }
        qlist[j]=i;
        p=j;
        vj=vlist[j];
        vk=vlist[k];
        while(k!=-1){
#if rev
          if((j==-1)|(vj<vk))
#else
          if((j==-1)|(vj>vk))
#endif
          {
            l=plist[k];
            plist[k]=plist[m];
            plist[m]=k;
            m=k;
            k=l;
            vk=vlist[k];
          }else{
            m=j;
            j=plist[j];
            vj=vlist[j];
          }
        }
      }
    }
    if(h==ss){
      c[h][0]=s;
    }else{
#if rev
      plist[c[h+1][1]]=s;
#else
      plist[c[h-1][1]]=s;
#endif
    }
    for(i=c[h][2];i!=-1;i=plist[i]) j=i;
    c[h][1]=j;
  }
  return(c[ss][0]);
}

int main(){
  int n,i,j,m,p[smaxn];
  long v[smaxn],l;
  char s[11];
  scanf("%d",&n);
  for(i=0;i<n;i++){
    scanf("%s",&s);
    v[i]=0;
    for(j=0;s[j]!=0;j++){
      v[i]|=((long)(s[j]-'a'+1))<<(45-j*5);
    }
  }
  m=1;
  i=sort(&v,&p,n);
  l=v[i];
  for(i=p[i];i!=-1;i=p[i]){
    if(l!=v[i]){
      l=v[i];
      m++;
    }
  }
  printf("%d",m);
  return(0);
}