#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
 
#define fast { ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define pb push_back
#define ll long long
#define ld long double
 
#define vi vector<int>
#define vl vector<long>
#define vll vector<long long>
 
#define infi INT_MAX
#define infl LONG_LONG_MAX
#define infd LDBL_MAX
#define f(i,a,b) for(ll i=a;i<b;i++)
#define fi(i,a,b) for(ll i=(b-1);i>=a;i--)
#define F first
#define S second
#define G(a,b) get<a>(b)
#define MP make_pair
#define MT make_tuple
#define pll pair<ll,ll> 
#define endl "\n"
#define ALL(v) v.begin(),v.end()
#define nl cout<<"\n";
#define pr(x) cout<<x;
#define pr1(x) cout<<x<<" ";
#define pr2(x,y) cout<<x<<" "<<y;
#define deb printf("***************************************************************************************\n");
#define moshi printf("moshi moshi ! \n");
#define hi printf("hi ! \n");
#define bye printf("bye bye ! \n");
#define o_set(ll) tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>


//template<typename T>
//#define o_set(T) tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update>
//member functions :
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set


//const ll N=1e6+7;
ll p=998244353;
//ll fac[N];

ll gcd(ll a, ll b) 
{ 
    if (a == 0) 
        return b; 
    return gcd(b % a, a); 
} 

inline ll ceil(ll a,ll b)
{
  return (a+b-1)/b;
}

ll max(ll x,ll y,ll z)
{
  return max(x,max(y,z));
}


ll modpro(ll x,ll y,ll z=1)
{
  x%=p;
  y%=p;
  z%=p;
  ll res=(x*y)%p;
  res=(res*z)%p;
  return res;
}

ll modadd(ll x,ll y,ll z=0)
{
  ll res=(x+y)%p;
  res=(res+z)%p;
  return res;
}


ll pow_mod_p(ll a,ll b)
{
  a=a%p;
  ll res=1;
  while(b>0)
  {
    if(b&1) res=(res*a)%p;
    b=b>>1;
    a=(a*a)%p;
  }
  return res;
}

inline ll mod_inv(ll x)
{
  return pow_mod_p(x,p-2);
}

/*
ll nCr(ll x,ll y)
{
  if(x<y) return 0;
  ll res=fac[x];
  ll den=(fac[y]*fac[x-y])%p;
  ll deni=mod_inv(den);
  res=(res*deni)%p;
  return res;
}*/


struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// resize : str.resize(new_size)   new size <= old size

// for Vector :
// lower_bound(starting iterator , iterator next to end , value)  :  iterator to first element greater than or equal to value
// upper_bound(starting iterator , iterator next to end , value)  :  iterator to first element strictly greater than value

// For Set :      s.lower_bound(value)
// if no such element exists they return  vector.end() or s.end()


// x bits : [x-1 , x-2 , .... , 1(1st bit) , 0(0th bit)] =>   leftmost 1 at 2^(x-1)    max number that can be represented : 2^(x) -1
// 63 bits is greater than 10^18

// 1<<x  :  2 ^ x  (left shift)

// Min heap :  priority_queue < ll , vector<ll>, greater<ll> > q  
// Max heap :  priority_queue < ll > q
// Set in descending order  :   set< ll,greater <ll> >


// While debugging : 
// 1 : check if array size is correct  :  It may give unexpected results
// 2 : check if you have swapped i and j at some part of program
// 3 : for string check if you are trying to acces  index = -1 

// l and r are for query
// tl : tree left   tr : tree right
ll query(ll v, ll tl, ll tr, ll l, ll r,ll *st) 
{
    if (l > r) return 0;
        
    if (l == tl && r == tr) return st[v];

    ll tm = (tl + tr) / 2;
    return query(v*2, tl, tm, l, min(r, tm),st)
           + query(v*2+1, tm+1, tr, max(l, tm+1), r,st);
}


void update(ll v, ll tl, ll tr, ll pos, ll new_val,ll *st) {
    if (tl == tr) {
        st[v] = new_val;
    } else {
        ll tm = (tl + tr) / 2;
        if (pos <= tm)
            update(v*2, tl, tm, pos, new_val,st);
        else
            update(v*2+1, tm+1, tr, pos, new_val,st);
        st[v] = st[v*2] + st[v*2+1];
    }
}

/*
const int N = 1e5;  // limit for array size
int n;  // array size
int t[2 * N];

void build() {  // build the tree
  for (int i = n - 1; i > 0; --i) t[i] = t[i<<1] + t[i<<1|1];
}*/
/*
void modify(ll p, ll value,ll *st, ll n) {  // set value at position p
  for (st[p += n] = value; p > 1; p >>= 1) st[p>>1] = st[p] + st[p^1];
}

ll query(ll l, ll r,ll *st,ll n) {  // sum on interval [l, r)
  ll res = 0;
  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
    if (l&1) res += st[l++];
    if (r&1) res += st[--r];
  }
  return res;
}*/


void func()
{
  ll n;
  cin>>n;
  map<string,ll>mp;
  f(i,1,n+1)
  {
    string s;
    cin>>s;
    mp[s]++;
  }
  pr(mp.size()) nl
}   


int main() 
{
    fast
    //#ifndef ONLINE_JUDGE
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    //#endif // ONLINE_JUDGE


    ll ntc=1;
    //cin>>ntc;

    f(i,1,ntc+1)
    {
      //cout<<"Case #"<<i<<": ";
      func();
    }
 
    return 0;
}



Measured memory_bytes: 19276