import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;

public class Main {

	private static BufferedReader brStdin = new BufferedReader(new InputStreamReader(System.in));
	private static String[] readBuf = null;
	private static int readPtr = 0;
	private static String getString() throws IOException {
		while ( readBuf == null || readPtr >= readBuf.length ) {
			readBuf = brStdin.readLine().split(" ");
			readPtr = 0;
		}
		return readBuf[readPtr++];
	}
	private static int getInt() throws IOException {
		return Integer.parseInt(getString());
	}
	private static long getLong() throws IOException {
		return Long.parseLong(getString());
	}
	private static BigDecimal getBD() throws IOException {
		return new BigDecimal(getString());
	}
	@SuppressWarnings("unused")
	private static String[] getStringArray(int size) throws IOException {
		String stringArray[] = new String[size];
		for (int i = 0; i < stringArray.length; i++) {
			stringArray[i] = getString();
		}
		return stringArray;
	}
	@SuppressWarnings("unused")
	private static int[] getIntArray(int size) throws IOException {
		int intArray[] = new int[size];
		for (int i = 0; i < intArray.length; i++) {
			intArray[i] = getInt();
		}
		return intArray;
	}
	@SuppressWarnings("unused")
	private static long[] getLongArray(int size) throws IOException {
		long longArray[] = new long[size];
		for (int i = 0; i < longArray.length; i++) {
			longArray[i] = getLong();
		}
		return longArray;
	}
	@SuppressWarnings("unused")
	private static BigDecimal[] getBDArray(int size) throws IOException {
		BigDecimal bdArray[] = new BigDecimal[size];
		for (int i = 0; i < bdArray.length; i++) {
			bdArray[i] = getBD();
		}
		return bdArray;
	}

	public static void main(String args[]) throws IOException {
		char c[] = getString().toCharArray();
		if (c[0]==c[1]&&c[2]==c[3]&&c[0]!=c[2] || c[0]==c[2]&&c[1]==c[3]&&c[0]!=c[1] || c[0]==c[3]&&c[1]==c[2]&&c[0]!=c[1] ) {
			System.out.println("Yes");
		} else {
			System.out.println("No");
		}

	}
}


import java.util.Scanner;

public class Main {
	public static void main(String[] args){
		Scanner stdIn = new Scanner(System.in);
		String S = stdIn.next();
		if(S.charAt(0) == S.charAt(1) && S.charAt(2) == S.charAt(3)){
			System.out.println("Yes");
		}
		else if(S.charAt(0) == S.charAt(2) && S.charAt(1) == S.charAt(3)){
			System.out.println("Yes");
		}
		else if(S.charAt(0) == S.charAt(3) && S.charAt(1) == S.charAt(2)){
			System.out.println("Yes");
		}
		else{
			System.out.println("No");
		}
		stdIn.close();
	}
}


import java.util.*; import java.io.*; import java.math.*;
public class Main{
	//Don't have to see. start------------------------------------------
	static class InputIterator{
		ArrayList<String> inputLine = new ArrayList<String>(1024);
		int index = 0; int max; String read;
		InputIterator(){
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			try{
				while((read = br.readLine()) != null){
					inputLine.add(read);
				}
			}catch(IOException e){}
			max = inputLine.size();
		}
		boolean hasNext(){return (index < max);}
		String next(){
			if(hasNext()){
				return inputLine.get(index++);
			}else{
				throw new IndexOutOfBoundsException("There is no more input");
			}
		}
	}
	static HashMap<Integer, String> CONVSTR = new HashMap<Integer, String>();
	static InputIterator ii = new InputIterator();//This class cannot be used in reactive problem.
	static PrintWriter out = new PrintWriter(System.out);
	static void flush(){out.flush();}
	static void myout(Object t){out.println(t);}
	static void myerr(Object t){System.err.print("debug:");System.err.println(t);}
	static String next(){return ii.next();}
	static boolean hasNext(){return ii.hasNext();}
	static int nextInt(){return Integer.parseInt(next());}
	static long nextLong(){return Long.parseLong(next());}
	static double nextDouble(){return Double.parseDouble(next());}
	static ArrayList<String> nextStrArray(){return myconv(next(), 8);}
	static ArrayList<String> nextCharArray(){return myconv(next(), 0);}
	static ArrayList<Integer> nextIntArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Integer> ret = new ArrayList<Integer>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Integer.parseInt(input.get(i)));
		}
		return ret;
	}
	static ArrayList<Long> nextLongArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Long> ret = new ArrayList<Long>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Long.parseLong(input.get(i)));
		}
		return ret;
	}
	static String myconv(Object list, int no){//only join
		String joinString = CONVSTR.get(no);
		if(list instanceof String[]){
			return String.join(joinString, (String[])list);
		}else if(list instanceof ArrayList){
			return String.join(joinString, (ArrayList)list);
		}else{
			throw new ClassCastException("Don't join");
		}
	}
	static ArrayList<String> myconv(String str, int no){//only split
		String splitString = CONVSTR.get(no);
		return new ArrayList<String>(Arrays.asList(str.split(splitString)));
	}
	public static void main(String[] args){
		CONVSTR.put(8, " "); CONVSTR.put(9, "\n"); CONVSTR.put(0, "");
		solve();flush();
	}
	//Don't have to see. end------------------------------------------
	static void solve(){//Here is the main function
		  ArrayList<String> s = nextCharArray();
		  HashMap<String, Integer> map = new HashMap<String, Integer>();
		  for(var i = 0; i < 4; i++){
		    if(!map.containsKey(s.get(i))){
		      map.put(s.get(i), 0);
		    }
		    map.put(s.get(i), map.get(s.get(i)) + 1);
		  }
		  Iterator keys = map.keySet().iterator();
		  while(keys.hasNext()){
		  	String k = (String)keys.next();
		  	if(map.get(k) != 2){
		  		myout("No");
		  		return;
		  	}
		  }
		  myout((keys.size() != 2) ? "No" : "Yes");
	}
	//Method addition frame start

	//Method addition frame end
}


//###################################################
import static java.lang.Math.ceil;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
//        int k = sc.nextInt();
//        int n = sc.nextInt();
//        int a = sc.nextInt();
//        int b = sc.nextInt();
//        int c = sc.nextInt();
//          int a1 = sc.nextInt();
//          int a2 = sc.nextInt();
//          int a3 = sc.nextInt();
//        int c = sc.nextInt();
//        int r = sc.nextInt();
//        int x = sc.nextInt();
//        int s = sc.nextInt();
//        double n = sc.nextDouble();
//        int r = sc.nextInt();
//        String s = sc.next();
//        String t = sc.next();
//        int n = sc.nextInt();
//        int m = sc.nextInt();
//        char c = sc.next().charAt(0);
        sc.close();
        String[] array =  s.split("");
        Arrays.sort(array); // 昇順
//        System.out.println("[0]: "+array[0]);
//        System.out.println("[1]: "+array[1]);
//        System.out.println("[2]: "+array[2]);
//        System.out.println("[3]: "+array[3]);
        if(array[0].equals(array[1]) && array[2].equals(array[3]) && array[0].equals(array[3])){
            System.out.println("Yes");
        }else{
            System.out.println("No");
        }
//        a *= n;
//        if(a <= b){
//            System.out.println(a);
//        }else{
//            System.out.println(b);
//        }
//        System.out.println();
//        double k = (a+b)/2.0;
//        if(k == ceil(k)){
//            System.out.println((int)k);
//        }else{
//            System.out.println("IMPOSSIBLE");
//        }

//        if(c-(a-b) >= 0 ){
//            System.out.println(c-(a-b));
//        }else{
//            System.out.println(0);
//        }
//        Integer array[] = {a+b,a-b,a*b};
//        Arrays.sort(array); // 昇順
//        Arrays.sort(array, Collections.reverseOrder()); // 降順
//        System.out.println(array[0]);
//        if(a>=3200){
//            System.out.println(s);
//        }else{
//            System.out.println("red");
//        }
//        String[] s_arr =  s.split("");
//        String[] t_arr =  t.split("");
//        int count=0;
//        for(int i = 0;i<s_arr.length;i++){
//            if(s_arr[i].equals(t_arr[i])){
//                count++;
//            }
//        }
//        System.out.println(count);
//        switch (s) {
//            case "Sunny":
//                System.out.println("Cloudy");
//                break;
//            case "Rainy":
//                System.out.println("Sunny");
//                break;
//            case "Cloudy":
//                System.out.println("Rainy");
//                break;
//        }
//        String array[] = {"SAT","FRI","THU","WED","TUE","MON","SUN"};
//        int count = 0;
//        for(int i = 1;i<array.length;i++){
//            if(s.equals(array[i])){
//                count += i;
//            }
//        }
//        if(n%2 == 0){
//            System.out.println(0.5000000000);
//        }else{
//            System.out.println(((n+1)/2)/n);
//        }
//        if(a<=b*2){
//            System.out.println(0);
//        }else{
//            System.out.println(a - 2*b);
//        }
//        if(a1 + a2 + a3 <= 21){
//            System.out.println("win");
//        }else{
//            System.out.println("bust");
//        }
//        Integer array[] = {a,b};
//        if(!Arrays.asList(array).contains(1)){
//            System.out.println(1);
//        }else if(!Arrays.asList(array).contains(2)){
//            System.out.println(2);
//        }else{
//            System.out.println(3);
//        }
//        if(k * 500 >= x){
//            System.out.println("Yes");
//        }else{
//            System.out.println("No");
//        }
//        char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
//        int i = 0;
//        for(;;){
//            if(alphabet[i] == c){
//                break;
//            }
//            i ++;
//        }
//        System.out.println(alphabet[i+1]);
//        if(n == m){
//            System.out.println("Yes");
//        }else{
//            System.out.println("No");
//        }
//        int count = 0;
//        for(;;){
//            if(h<=0){
//                break;
//            }
//            h -= a;
//            count ++;
//        }
////        System.out.println(h);
//        System.out.println(count);
//        String[] arr =  s.split(" ");
////        System.out.println(arr[0]);
//        System.out.println(arr[1]);
//        System.out.println(a);
//        System.out.println(b);
//        System.out.println(u);
//        if(arr[0].equals(u)){
//            a -= 1;
//            System.out.println(a+" "+b);
//        }else{
//            b -= 1;
//            System.out.println(a+" "+b);
//        }
//        List<Integer> list = Arrays.asList(a,b,c);
////        System.out.println(list);
//        List<Integer> list2 = new ArrayList<Integer>(new HashSet<>(list));
//        if(list2.size() == 2){
//            System.out.println("Yes");
//        }else{
//            System.out.println("No");
//        }
//        System.out.println(list2);
//        if(n >= 10){
//            System.out.println(r);
//        }else{
//            System.out.println(r + 100*(10-n));
//        }
//        if(n % 2 == 0){
//            n = (n/2);
//            System.out.println(n);
//        }else{
//            n = n/2 + 1;
//            System.out.println(n);
//        }
//        int sum = 0;
//        sum = n*(n-1)/2 + m*(m-1)/2;
//        System.out.println(sum);
//        String[] arr =  s.split("");
//         System.out.println("arr[2]: "+arr[2]);
//          System.out.println("arr[3]: "+arr[3]);
//           System.out.println("arr[4]: "+arr[4]);
//            System.out.println("arr[5]: "+arr[5]);
//        if(arr[2].equals(arr[3]) && arr[4].equals(arr[5])){
//            System.out.println("Yes");
//        }else{
//            System.out.println("No");
//        }
//        System.out.println(z + " " + x + " " + y);
//        if(n.contains("7")){
//            System.out.println("Yes");
//        }else{
//            System.out.println("No");
//        }
//        System.out.println(n);
//        if(s <= w){
//            System.out.println(Math.PI);
//        }else{
//            System.out.println("safe");
//        }
//        System.out.println(s);
//        if(s.contains("RRR")){
//            System.out.println(3);
//        }else if(s.contains("RR")){
//            System.out.println(2);
//        }else if(s.contains("R")){
//            System.out.println(1);
//        }else{
//             System.out.println(0);
//        }
//        String s = sc.nextLine();
//        String t = sc.next();
//        String[] arr =  s.split("　");
//        sc.close();
//        System.out.println("input: "+ s);
//        System.out.println("k:" + k);
//        System.out.println("a:" + a);
//        System.out.println("b:" + b);
//        String ans = "NG";
//        for(int x = a; x<=b; x++){
//            if(x%k == 0){
//                ans = "OK";
//            }
//        }
//        System.out.println(ans);
//        \
//        System.out.println("arr[1]:" + arr[1]);
//
//        if(s.equals("ABC")){
//            System.out.println("ARC");
//        }else{
//            System.out.println("ABC");
//        }
//        String[] arr1 =  s.split("");
//        String[] arr2 =  t.split("");
////        List<String> list1 = Arrays.asList(s.split(""));
//        List list1 = new LinkedList(Arrays.asList(s.split("")));
////        List<String> list2 = Arrays.asList(t.split(""));
//        List list2 = new LinkedList(Arrays.asList(t.split("")));
////        int num = Integer.parseInt(arr[arr.length - 1]);
//        list2.remove(arr2.length - 1);
////        System.out.println(list1);
////        System.out.println(list2);
//         if(list1.toString().contentEquals(list2.toString())){
//             System.out.println("Yes");
//         }else{
//             System.out.println("No");
//         }
//        switch(num){
//            case 3:
//                System.out.println("bon");
//                break;
//            case 0:
//            case 1:
//            case 6:
//            case 8:
//                System.out.println("pon");
//                break;
//            default:
//                System.out.println("hon");
//                break;
//        }
//        String[] array = str.split(" ");
//        int sum = 0;
//        for(int i=0; i<array.length; i++) {
//            int num = Integer.parseInt(array[i]);
//            sum += num;
//        }
//        System.out.println(15-sum);
    }
}


#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>
#include <iterator>
#include <assert.h>
#pragma warning(disable:4996)

typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
const long long MOD = 1000000007;
using namespace std;

int main(int argc, char* argv[])
{
    char str[5]={0};
    scanf("%s", str);
    sort(str+0, str+4);
    if(str[0]==str[1] && str[2]==str[3] && str[1]!=str[2]) {
        printf("Yes\n");
    }
    else {
        printf("No\n");
    }

    return 0;
}


#include<stdio.h>

int main(){
    char str[4] ;
    scanf("%s",&str);
    int count = 0  , i , j;
    for(i = 0 ; i < 3 ; i++){
        for(j = i+1 ; j<4 ; j++){
            if(str[i]==str[j]){
                count++ ;
                break ;
            }
        }
    }
    if(count==2){
        printf("Yes");
    }else{
        printf("No");
    }

}


#include <cstdio>
#include <unordered_set>
const int MAXA = 26;
const int MAXS = 4;
const int TWO = 2;
int cnt[MAXA]{ };
char S[MAXS + 5];

int main() {
  scanf("%s", S);
  int two = 0;
  for (int i = 0; i < MAXS; ++i) {
    int c = S[i] - 'A';
    ++cnt[c];
    if (cnt[c] == TWO) {
      ++two;
    } else if (cnt[c] > TWO) {
      --two;
    }
  }
  puts((two == TWO) ? "Yes" : "No");
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin >> s;
    if(s[0]==s[1]==s[2]==s[3]){
        cout<<"No"<<endl;
        return 0;
    }
    if((s[0]==s[1] && s[2]==s[3]) || (s[0]==s[2] && s[1]==s[3]) || (s[0]==s[3] && s[1]==s[2]))cout << "Yes"<<endl;
    else cout<<"No"<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin >> s;
    if((s[0]==s[1] && s[2]==s[3]) || (s[0]==s[2] && s[1]==s[3]) || (s[0]==s[3] && s[1]==s[2]))cout << "Yes"<<endl;
    else cout<<"No"<<endl;
}


#pragma GCC optimize("O3")

#define _GLIBCXX_DEBUG
#include <iostream>
#include <vector>
#include <string>
#include <string_view>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cassert>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
using namespace std;

/*----------macros----------*/

//input, output================
#define fastio                          \
std::ios::sync_with_stdio(false);       \
std::cin.tie(nullptr);                  \
std::cout.tie(nullptr)

#define endl '\n'
#define fcout(a)                        \
cout << fixed << setprecision((int)(a))

//typedef===============
typedef long long       ll;
typedef long double     ld;
typedef vector<int>     Vi;
typedef vector<ll>      Vl;
typedef pair<int, int>  Pii;
typedef pair<ll, ll>    Pll;

//const number==========
constexpr ll INF    = (ll)1e9 + 1;
constexpr ll INFll  = (ll)1e18 + 1;
constexpr ll MOD1   = 1000000007;
constexpr ll MOD2   = 998244353;
constexpr ld PI     = 3.141592653589793L;

//member================
#define psb push_back
#define epb emplace_back
#define psf push_front
#define mkp make_pair
#define fst first
#define snd second

//others================
#define sz(x)                           \
(int) x.size()

#define all(x)                          \
(x).begin(), (x).end()

#define rall(x)                         \
(x).rbegin(), (x).rend()

#define rep(i, n)                       \
for(int i = 0; (i) < (n); ++(i))

#define reps(i, n)                      \
for(int i = 1; (i) <= (n); ++(i))

#define rrep(i, n)                      \
for(int i = n - 1; (i) >= 0 ; --(i))

#define repbit(bit, n)                  \
for(int bit = 0; (bit) < (1 << (n)); ++(bit))

#define ifbit(bit, i)                   \
if((bit) & (1 << (i)))

#define CtoI(c)                         \
int((c)) - int('0')

#define ItoC(c)                         \
char((c) + '0')

//functions=============
template<typename T1, typename T2>
inline bool chmax(T1 &a, T2 b)
{ return a < b && (a = b, true); }

template<typename T1, typename T2>
inline bool chmin(T1 &a, T2 b)
{ return a > b && (a = b, true); }

// Vi  dx = {1, 0, -1, 0},
//     dy = {0, 1, 0, -1};

// Vi  dx2 = { 1,1,0,-1,-1,-1,0,1 },
//     dy2 = { 0,1,1,1,0,-1,-1,-1 };

/*--------additional--------*/

/*----------main------------*/

int main() {
fastio;

    string s; cin >> s;
    if((s[0] == s[1] && s[2] == s[3]) ||
       (s[0] == s[2] && s[1] == s[3]) ||
       (s[0] == s[3] && s[1] == s[2]) ||
       (s[1] == s[3] && s[0] == s[2]) ||
       (s[2] == s[3] && s[0] == s[1])){
           cout << "Yes" << endl;
           return 0;
       }

       cout << "No" << endl;

return 0;
}


#include <stdio.h>
#include <stdlib.h>
int asc(const void *a, const void *b){
    return *(char*)a-*(char*)b;
}
int main(void){
    char s[5];
    scanf("%s",s);
    qsort(s,4,sizeof(char),asc);
    if(s[0]==s[1] && s[2]==s[3] && s[0]!=s[2]) printf("Yes");
    else printf("No");
    return 0;
}


#include <stdio.h>
int main(){
    char S[4];
    scanf("%s",S);
    if(S[0]==S[1]){
        if(S[2]==S[3]){
            if(S[0]!=S[2]){
                printf("Yes");
                return 0;
            }
        }
    }
    if(S[0]==S[2]){
        if(S[1]==S[3]){
            if(S[0]!=S[1]){
                printf("Yes");
                return 0;
            }
        }
    }
    if(S[0]==S[3]){
        if(S[1]==S[2]){
            if(S[0]!=S[1]){
                printf("Yes");
                return 0;
            }
        }
    }
    printf("No");
}


#include <stdio.h>

int main(void) {
    char s[5];

    scanf("%s", s);

    if (s[0] == s[1] && s[1] == s[2] && s[2] == s[3]) {
        printf("No\n");
    }
    else if (s[0] == s[1] && s[2] == s[3]) {
        printf("Yes\n");
    }
    else if (s[0] == s[2] && s[1] == s[3]) {
        printf("Yes\n");
    }
    else if (s[0] == s[3] && s[1] == s[2]) {
        printf("Yes\n");
    }
    else {
        printf("No\n");
    }

    return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef long long ll;
typedef char keytype;

void quicksort_des(keytype a[], int first, int last)
{
    int i, j;
    keytype x, t;

    x = a[(first + last) / 2];
    i = first;  j = last;
    for ( ; ; ) {
        while (a[i] > x) i++;
        while (x > a[j]) j--;
        if (i >= j) break;
        t = a[i];  a[i] = a[j];  a[j] = t;
        i++;  j--;
    }
    if (first  < i - 1) quicksort_des(a, first , i - 1);
    if (j + 1 < last) quicksort_des(a, j + 1, last);
}

int main(){
    char s[5];

    scanf("%s", s);

    quicksort_des(s, 0, 3);

    if(s[0] == s[1] && s[2] == s[3]) puts("Yes");
    else puts("No");

    return 0;
}


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

int main()
{

	string s;
	int cnt = 0;
	cin >> s;
	sort(s.begin(), s.end());
	for (int i = 0; i < s.length()-1; i++)
		if (s[i] == s[i + 1])
			cnt++;
	if (cnt == 2)
		cout << "Yes";
	else
		cout << "No";
}


#include<stdio.h>
int main()
{
	char s[4];
	scanf("%s",s);
	if(s[0]!=s[1]&&s[0]!=s[2]){
		if(s[0]==s[1]&&s[2]==s[3]||s[0]==s[2]&&s[1]==s[3]||s[0]==s[3]&&s[1]==s[2]){
			printf("Yes\n");
		}
	}
	else{
		printf("No\n");
	}
	return 0;
}


"use strict";

const main = arg => {
    let text = arg.trim().split("");
  	let ans = "No";
  	// 全部同じだった時の処理
  	if(text.every(elm => { return elm == text[0]})){
    	ans = "No";
    }
  	else if(
      (text[0] == text[1] && text[2] == text[3])
      ||
      (text[0] == text[2] && text[1] == text[3])
      ||
      (text[0] == text[3] && text[1] == text[2])
  	)
    {
    	ans = "Yes";
    }
  	console.log(ans);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


'use strict'
const Main = (arg) => {
  let input = arg.trim().split('\n');
  let S = input[0].split('');
  // console.log({ S });
  let Ans = 'No';
  if (S[0] === S[1] && S[2] === S[3] && S[0] !== S[2]) {
    Ans = 'Yes'
  } else if (S[0] === S[2] && S[1] === S[3] && S[0] !== S[1]) {
    Ans = 'Yes'
  } else if (S[0] === S[3] && S[1] === S[2] && S[0] !== S[1]) {
    Ans = 'Yes'
  }

  console.log(Ans)
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  var a = input.slice(0, 1);
  var b = input.slice(1, 2);
  var c = input.slice(2, 3);
  var d = input.slice(3, 4);

  if((a == b && c == d && a != c)
    || (a != b && a == c && b == d)
    || (a != b && b == c && a == d)){
     console.log("Yes");
     }else{
       console.log("No");
     }
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const fs = require('fs')

const input = fs.readFileSync('/dev/stdin', 'utf8')

const S = input.trim()

const counter = {}

for (let i=0; i<4; i++) {
  const c = S.substr(i, 1)
  if (c in counter) {
    counter[c] = counter[c] + 1
  } else {
    counter[c] = 1
  }
}

if (counter[S.substr(0, 1)] === 2) {
  console.log('Yes')
} else {
  console.log('No')
}


"use strict";
function main(input) {
    let S = input.replace("\n", "");
    let ans = countBy([...S]);
    console.log(Object.values(ans)[0] == 2 ? "Yes" : "No");
    return;
}
function countBy(data, keyGetter) {
    var keyResolver = {
        'function': function (d) { return keyGetter(d); },
        'string': function (d) { return d[keyGetter]; },
        'undefined': function (d) { return d; }
    };

    var result = {};

    data.forEach(function (d) {
        var keyGetterType = typeof keyGetter;
        var key = keyResolver[keyGetterType](d);

        if (result.hasOwnProperty(key)) {
            result[key] += 1;
        } else {
            result[key] = 1;
        }
    });

    return result;
}
// list1 = ['a', 'b', 'c', 'b', 'a', 'b', 'c', 'a', 'a', 'a'];
// console.log(countBy(list1));  // {'a':5, 'b':3, 'c':2}
// list2 = ['abc', 'aa', 'b3', 'abcd', 'cd'];
// console.log(countBy(list2, 'length'));  // {2: 3, 3: 1, 4: 1}
// list3 = [1.2, 7.8, 1.9];
// console.log(countBy(list3, Math.floor));  // {1: 2, 7: 1}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


'use strict'
const Main = (arg) => {
  let S = arg.trim().split('\n');
  console.log({ S });
  Ans = 'No';
  if (S[0] === S[1] && S[2] === S[3] && S[0] !== S[2]) {
    Ans = 'Yes'
  } else if (S[0] === S[2] && S[1] === S[3] && S[0] !== S[1]) {
    Ans = 'Yes'
  } else if (S[0] === S[3] && S[1] === S[2] && S[0] !== S[1]) {
    Ans = 'Yes'
  }

  console.log(Ans)
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

func main() {
	sc.Split(bufio.ScanWords)
	s := getString()

	m := make(map[byte]int)
	for _, v := range s {
		m[byte(v)]++
	}
	if len(m) == 2 {
		for _, v := range m {
			if v != 2 {
				out("No")
				return
			}
		}
		out("Yes")
		return
	}
	out("No")
	return
}


package main

import (
	"fmt"
)

const MOD = 1000000007

func ModAdd(a, b int64) int64 {
	return (a + b) % MOD
}

func ModMul(a, b int64) int64 {
	return a * b % MOD
}

func ModSub(a, b int64) int64 {
	r := (a%MOD - b%MOD) % MOD
	if r < 0 {
		r += MOD
	}
	return r
}

func ModDiv(a, b int64) int64 {
	return a % MOD * ModInv(b) % MOD
}

func ModPow(a, n int64) int64 {
	var r int64 = 1
	for n > 0 {
		if n&1 == 1 {
			r = r * a % MOD
		}
		a = a * a % MOD
		n >>= 1
	}
	return r
}

func ModInv(a int64) int64 {
	var b, u, v int64 = MOD, 1, 0
	for b > 0 {
		t := a / b
		a -= t * b
		a, b = b, a
		u -= t * v
		u, v = v, u
	}
	u %= MOD
	if u < 0 {
		u += MOD
	}
	return u
}

type Q struct {
	idx, value int
	a, b       int
	index      int
}

type QS []*Q

func (p QS) Len() int           { return len(p) }
func (p QS) Less(i, j int) bool { return p[i].value > p[j].value }
func (pq QS) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *QS) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Q)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *QS) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil  // avoid memory leak
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func FactoredPrimeNumber(num int) map[int]int {
	m := map[int]int{}
	return factor(m, num, 2)
}

func factor(result map[int]int, num, pnum int) map[int]int {
	if pnum*pnum > num {
		if num != 1 {
			result[num] += 1
		}
		return result
	}

	if num%pnum == 0 {
		num /= pnum
		result[pnum]++
	} else {
		pnum++
	}
	return factor(result, num, pnum)
}

func GCD(a, b int) int {
	if b == 0 {
		return a
	}
	return GCD(b, a%b)
}

func LCM(a, b int) int {
	return a * b / GCD(a, b)
}

type P struct {
	l, r int
}

func main() {
	var S string
	fmt.Scanf("%s\n", &S)

	m := map[string]int{}

	for _, s := range []rune(S) {
		m[string(s)]++
	}
	if len(m) == 2 {
		for _, v := range m {
			if v == 2 {
				fmt.Println("Yes")
				return
			}
		}
	}

	fmt.Println("No")
}

func Reverse(runes []rune) []rune {
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return runes
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	S := readString()
	m := map[byte]int64{}
	for i := 0; i < len(S); i++ {
		m[S[i]]++
	}
	for _, v := range m {
		if v != 2 {
			fmt.Println("No")
			return
		}
	}
	fmt.Println("Yes")
	return
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"fmt"
)

func main() {

	var S string
	fmt.Scanf("%s", &S)

	if (S[0] == S[1] && S[2] == S[3]) || (S[0] == S[2] && S[1] == S[3]) || (S[0] == S[3] && S[1] == S[2]) {
		fmt.Println("Yes")
	} else {
		fmt.Println("No")
	}
}


	package main

	import (
		"bufio"
		"fmt"
		"os"
		"sort"
		"strings"
	)

	var mod = 1000000007

	func main() {
		r := bufio.NewReader(os.Stdin)
		var s string
		fmt.Fscan(r, &s)

		tmp := strings.Split(s, "")
		sort.Strings(tmp)

		if tmp[0] == tmp[1] && tmp[2] == tmp[3] {
			fmt.Println("Yes")
		} else {
			fmt.Println("No")
		}
	}

	// Union-Find
	type unionFind struct {
		d []int
	}

	func newUnionFind(n int) *unionFind {
		uf := new(unionFind)
		uf.d = make([]int, n)
		for i := 0; i < n; i++ {
			uf.d[i] = -1
		}
		return uf
	}

	func (uf *unionFind) find(x int) int {
		if uf.d[x] < 0 {
			return x
		}
		uf.d[x] = uf.find(uf.d[x])
		return uf.d[x]
	}

	func (uf *unionFind) unite(x, y int) bool {
		rootX := uf.find(x)
		rootY := uf.find(y)
		if rootX == rootY {
			return false
		}

		if uf.d[rootX] < uf.d[rootY] {
			uf.d[rootX] += uf.d[rootY]
			uf.d[rootY] = rootX
		} else {
			uf.d[rootY] += uf.d[rootX]
			uf.d[rootX] = rootY
		}

		return true
	}

	func (uf *unionFind) same(x, y int) bool {
		return uf.find(x) == uf.find(y)
	}

	func (uf *unionFind) size(x int) int {
		return -uf.d[uf.find(x)]
	}

	// mod
	func modpow(a, n, mod int) int {
		res := 1
		for n > 0 {
			if n%2 != 0 {
				res = res * a % mod
			}
			a = a * a % mod
			n = n / 2
		}
		return res
	}

	func modinv(n, mod int) int {
		return modpow(n, mod-2, mod)
	}

	func modcomb(n, a, mod int) int {
		x := 1
		y := 1
		for i := 0; i < a; i++ {
			x = x * (n - i)
			x %= mod
			y = y * (i + 1)
			y %= mod
		}
		return x * modpow(y, mod-2, mod) % mod
	}

	func modfactorial(n, mod int) int {
		result := 1
		for i := 1; i <= n; i++ {
			result = (result * i) % mod
		}
		return result
	}

	// Combination ...
	type Combination struct {
		facts, invs []int
		mod         int
	}

	// NewCombination ...
	func NewCombination(n, mod int) Combination {
		return Combination{
			facts: make([]int, n+1),
			invs:  make([]int, n+1),
			mod:   mod,
		}
	}

	func (cmb *Combination) calc(n, k int) int {
		ret := cmb.facts[n] * cmb.invs[k]
		ret %= cmb.mod
		ret = ret * cmb.invs[n-k]
		ret %= cmb.mod
		return ret
	}

	func (cmb *Combination) init(n int) {
		cmb.facts[0] = 1
		// 階乗を算出
		for i := 1; i <= n; i++ {
			cmb.facts[i] = cmb.facts[i-1] * i % cmb.mod
		}
		// 逆元を算出
		cmb.invs[n] = modinv(cmb.facts[n], cmb.mod)
		for i := n - 1; i >= 0; i-- {
			cmb.invs[i] = cmb.invs[i+1] * (i + 1) % cmb.mod
		}
	}

	// Utility
	func min(x, y int) int {
		if x < y {
			return x
		}
		return y
	}

	func max(x, y int) int {
		if x > y {
			return x
		}
		return y
	}

	func abs(x int) int {
		if x < 0 {
			return -x
		}
		return x
	}

	func primeFactor(x int) map[int]int {
		res := make(map[int]int)
		for i := 2; i*i <= x; i++ {
			for x%i == 0 {
				res[i]++
				x = x / i
			}
		}
		if x != 1 {
			res[x] = 1
		}
		return res
	}

	func divisor(x int) []int {
		res := make([]int, 0)
		for i := 1; i*i <= x; i++ {
			if x%i == 0 {
				res = append(res, i)
				if i != x/i {
					res = append(res, x/i)
				}
			}
		}
		return res
	}

	func gcd(x, y int) int {
		if y == 0 {
			return x
		}
		return gcd(y, x%y)
	}

	func lcm(x, y int) int {
		return x / gcd(x, y) * y
	}

	func reverseString(s string) string {
		r := []rune(s)
		for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
			r[i], r[j] = r[j], r[i]
		}
		return string(r)
	}

	func pow(a, n int) int {
		ret := 1
		for i := 1; i <= n; i++ {
			ret *= a
		}
		return ret
	}

	// Queue ...
	type Queue []int

	// pop ...
	func (q *Queue) empty() bool {
		return len(*q) == 0
	}

	// push ...
	func (q *Queue) push(i int) {
		*q = append(*q, i)
	}

	// pop ...
	func (q *Queue) pop() (int, bool) {
		if q.empty() {
			return 0, false
		} else {
			res := (*q)[0]
			*q = (*q)[1:]
			return res, true
		}
	}

	// Stack ...
	type Stack []int

	// pop ...
	func (s *Stack) empty() bool {
		return len(*s) == 0
	}

	// push ...
	func (s *Stack) push(i int) {
		*s = append(*s, i)
	}

	// pop ...
	func (s *Stack) pop() (int, bool) {
		if s.empty() {
			return 0, false
		} else {
			index := len(*s) - 1
			res := (*s)[index]
			*s = (*s)[:index]
			return res, true
		}
	}

	// priority_queue
	type intHeap []int

	func (h intHeap) Len() int           { return len(h) }
	func (h intHeap) Less(i, j int) bool { return h[i] > h[j] }
	func (h intHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
	func (h *intHeap) Push(x interface{}) {
		*h = append(*h, x.(int))
	}
	func (h *intHeap) Pop() interface{} {
		old := *h
		n := len(old)
		x := old[n-1]
		*h = old[0 : n-1]
		return x
	}

	// sortable points
	type point struct {
		x int
		y int
	}

	type points []point

	func (p points) Len() int {
		return len(p)
	}

	func (p points) Less(i, j int) bool {
		return p[i].x < p[j].x
	}

	func (p points) Swap(i, j int) {
		p[i], p[j] = p[j], p[i]
	}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var sc = bufio.NewReaderSize(os.Stdin, 1024*1024*1)

func main() {
	S := getStdin()
	var ch1 byte = ' '
	var ch2 byte = ' '
	for idx := range S {
		if ch1 == ' ' {
			ch1 = S[idx]
		} else if ch2 == ' ' && ch1 != S[idx] {
			ch2 = S[idx]
		} else {
			if ch1 != S[idx] && ch2 != S[idx] {
				fmt.Printf("No\n")
				return
			}
		}
	}
	fmt.Printf("Yes\n")
}

func getStdin() string {
	return readLine()
}
func getStdinInt() int {
	str := getStdin()
	rtn, _ := strconv.Atoi(str)
	return rtn
}
func getStdinInt64() int64 {
	str := getStdin()
	rtn, _ := strconv.ParseInt(str, 10, 64)
	return rtn
}
func getStdinIntArr() []int {
	str := getStdin()
	list := strings.Split(str, " ")
	rtn := make([]int, len(list))
	for idx, val := range list {
		rtn[idx], _ = strconv.Atoi(val)
	}
	return rtn
}

func getStdinArr() []string {
	str := getStdin()
	list := strings.Split(str, " ")
	return list
}

func getStdinIntArr64() []int64 {
	str := getStdin()
	list := strings.Split(str, " ")
	rtn := make([]int64, len(list))
	for idx, val := range list {
		rtn[idx], _ = strconv.ParseInt(val, 10, 64)
	}
	return rtn
}

func readLine() string {
	buf := make([]byte, 0, 0)
	for {
		l, p, e := sc.ReadLine()
		if e != nil {
			panic(e)
		}
		buf = append(buf, l...)
		if !p {
			break
		}
	}
	return string(buf)
}


len = gets.chomp.split('').uniq.length
puts len == 2 ? 'Yes' : 'No'


inputs = gets.chomp.split("")

result = {}

inputs.uniq.each { |x|
	result[x] = inputs.count(x)
}

if result.keys.size == 2 && result.values[0] == 2 && result.values[1] == 2 then
	puts 'Yes'
else
	puts 'No'
end

STDOUT.flush


s = gets.chomp.chars
count = Hash.new(0)
s.each do |c|
  count[c] += 1
  if count[c] > 2
    print("No\n")
    exit
  end
end

if count.length > 2
  print("No\n")
else
  print("Yes\n")
end


a,b,c,d=gets.chars.sort
puts a==b&&c==d&&b!=c ? "Yes":"No"


a,b,c,d=gets.chars.sort
puts a==b&&c==d ? "Yes":"No"


puts gets.chop.chars.tally.values.all{_1==2}?:Yes: :No


//! ----------------------------------------------
//! Framework <https://github.com/vain0x/procon>
//!
//! See the bottom of file for solution.
//! ----------------------------------------------

#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Display, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

/// Print values to standard error if debug mode.
#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), stderr());
            writeln!(err, "\x1B[33m{}\x1B[0m = {:?}", e, $e).unwrap()
        })*
    };
}

/// Read from standard input and parse each word.
/// - `read!(T, U, ..)` parses a line as a tuple of words.
/// - `read![[T]]` parses a line as an array of words.
/// - `read![..; N]` parses `N` lines, using `read!(..)` repeatedly.
#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

/// Read a line from standard input.
#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();

    #[allow(deprecated)]
    buf.trim_right().to_owned()
}

// -----------------------------------------------
// Solution
// -----------------------------------------------

fn main() {
    let mut S = rl().chars().collect::<Vec<_>>();
    S.sort();
    let ok = S[0] == S[1] && S[1] != S[2] && S[2] == S[3];
    println!("{}", if ok { "Yes" } else { "No" })
}


use std::cmp;

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input! {
    	n:chars
    }
    let mut nn = n.to_vec();
    nn.sort();

    println!("{}", if nn[0]==nn[1]&&nn[2]==nn[3]&&nn[1]!=nn[2] { "Yes" } else { "No" });
}


use std::io::*;
use std::str::FromStr;

/*
The read function reads a string according to each one.
*/
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

//main function
fn main() {
    let n: String = read();
    let ch: Vec<char> = n.chars().collect();
    let mut count: i32;
    for i in 0..ch.len(){
	count = 0;
	for j in 0..ch.len(){
	    if ch[i]==ch[j] {
		count+=1;
	    }
	}
	if count != 2 {
	    println!("No");
	    return;
	}
    }
    println!("Yes");
}


#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;

#[fastout]
fn main() {
    input! {
    mut s: Chars
    }
    s.sort();
    let ans = if s[0] == s[1] && s[2] == s[3] {"Yes"} else {"No"};
    println!("{}", ans);
}


#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use {
    proconio::{marker::*, *},
    std::{cmp::*, collections::*, mem::*},
};

#[fastout]
fn main() {
    input! {//
        s:Bytes,
    }
    if s[0] ^ s[1] ^ s[2] ^ s[3] == 0 {
        if s[0] != s[1] || s[1] != s[2] || s[2] != s[3] {
            println!("Yes");
            return;
        }
    }
    println!("No");
}


#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use {
    proconio::{marker::*, *},
    std::{cmp::*, collections::*, mem::*},
};

#[fastout]
fn main() {
    input! {//
        s:Bytes,
    }
    if (s[0] != s[1] || s[1] != s[2] || s[2] != s[3]) && s[0] ^ s[1] ^ s[2] ^ s[3] == 0 {
        println!("Yes");
    } else {
        println!("No");
    }
}


import Foundation

let input = readLine()!

let S = Array(input.characters)

if S[0] == S[1] && S[1] == S[2] && S[2] == S[3] {
	print("No")
}else if S[0] == S[2] && S[1] == S[3] {
    print("Yes")
} else if S[1] == S[2] && S[0] == S[3] {
    print("Yes")
} else if S[0] == S[1] && S[2] == S[3] {
    print("Yes")
} else {
    print("No")
}


let str=String((readLine()!).sorted())

let a=str.index(str.startIndex,offsetBy:0)
let b=str.index(str.startIndex,offsetBy:1)
let c=str.index(str.startIndex,offsetBy:2)
let d=str.index(str.startIndex,offsetBy:3)

if (str[a]==str[b])&&(str[b] != str[c])&&(str[c]==str[d]){
  print("Yes")
}else{
  print("No")
}


let s=readLine()!
var seta:Set<Character>=[]
var judge=0
for x in s{
  seta.insert(x)
}
if seta.count==2{
  judge+=1
}
for x in seta{
  var count=0
  for y in s{
    if x==y{
      count+=1
    }
  }
  if count==2{
    judge+=1
  }
}

if judge==3{
  print("Yes")
}else{
  print("No")
}


var str = String((readLine()!).sorted())

  let a = str.index(str.startIndex, offsetBy: 0)
  let b = str.index(str.startIndex, offsetBy: 1)
  let c = str.index(str.startIndex, offsetBy: 2)
  let d = str.index(str.startIndex, offsetBy: 3)

  if str [a]==str [b] && str [c]==str[d] {
    print("Yes")
  }
  else {
    print("No")
  }


let s=readLine()!
var seta:Set<Character>=[]
var judge=0
for x in s{
  seta.insert(x)
}
for x in seta{
  var count=0
  for y in s{
    if x==y{
      count+=1
    }
  }
  if count==2{
    judge+=1
  }
}

if judge==3{
  print("Yes")
}else{
  print("No")
}


let s=readLine()!
var seta:Set<Character>=[]
var judge=0
for x in s{
  seta.insert(x)
}
var count=0
for x in seta{
  for y in s{
    if x==y{
      count+=1
    }
  }
}
if (count==4) && (judge==1){
  print("Yes")
}else{
  print("No")
}


import { readFileSync } from 'fs'

function main(input: string) {
  const list = input.trim().split('')

  const result = list.every(char =>
    list.filter(c => c === char).length === 2
  )

  console.log(result ? 'Yes' : 'No')
}

main(readFileSync('/dev/stdin', 'utf8').trim())


'use strict'
const main = (input: string) => {
    const std = new Set(input.trim().split(''))
    std.size == 2 ? console.log("Yes") : console.log("No")
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'))


import * as fs from 'fs';

//in
// SASA
//out
// Yes
const main: any = (inp: string) => {
    if (inp[0] + inp[1] === inp[2] + inp[3]) {
        console.log('Yes');
    } else {
        console.log('No');
    }
};
main(fs.readFileSync('/dev/stdin', 'utf8').trim());


const input=require('fs').readFileSync('/dev/stdin', 'utf8').split(/[\s]/);const nin=()=>{const r = input[0];input.shift();return Number(r)};const nrin=(n)=>{const a:number[]=[];rep(n,()=>a.push(nin()));return a};const sin=()=>{const r = input[0];input.shift();return String(r)};const out=(...a)=>{console.log(...a)};const floor=(a)=>{return Math.floor(a)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const rep=(n, callback)=>{for(let i = 0;i < n; i++){callback()}};const strrep=(s, i, v)=>{return s.slice(0, i)+v+s.slice(i+1);};const permutation=({result=[],pre=[],post,n=post.length})=>{if(n>0){post.forEach((_,i)=>{const rest=[...post];const elem=rest.splice(i, 1);permutation({result, pre: [...pre,...elem],post:rest,n:n-1})})}else{result.push(pre)}return result};const sw=(s,a:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<a.length;i+=2){if(op==='=='){if(s==a[i])return a[i+1]}else if(op==='>='){if(s>=a[i])return a[i+1]}else if(op==='<='){if(s<=a[i])return a[i+1]}else if(op==='>'){if(s>a[i])return a[i+1]}else if(op==='<'){if(s<a[i])return a[i+1]}}return a[a.length-1];};const or=(a,...b)=>{for(let i=0;i<b.length;i++)if(a==b[i])return true;return false};const maxindex=(...a)=>{return a.indexOf(Math.max.apply(null,a))};const asc=(ar:number[])=>{return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{return ar.sort((a,b)=>{return b-a})};const ceil=a=>{return Math.ceil(a)};const srin=s=>{const a:string[]=[];rep(s,()=>a.push(sin()));return a};let ssinteger=-1;const ssin=()=>{ssinteger++;return input[0][ssinteger]};
const main = ()=>{
  let a=[ssin(),ssin(),ssin(),ssin()].sort()
  out(a[0]==a[1]&&a[2]==a[3]?'Yes':'No')
}
main()


'use strict'
const main = (input: string) => {
    const std: Set<String> = new Set(input.split(''))
    std.size == 2 ? console.log("Yes") : console.log("No")
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'))


# C - gacha
def main():
    _, *S = open(0)
    print(len(set(S)))

if __name__ == "__main__":
    main()


N = int(input())
lst = []
count = 0
for _ in range(N):
    s = input()
    if not s in lst:
        lst.append(s)
        count += 1
print(count)


N = int(input())
count = 0
for _ in range(N):
    s = input()
    if not s in lst:
        count += 1
print(count)


N = int(input())
lst = []
for _ in range(N):
    s = input()
    if not s in lst:
        lst.append(s)
print(len(lst))


import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
    public  static void main(String[] args) {
        FastScanner sc = new FastScanner();
        String text = "";
        List<String> listA = new ArrayList<>();
        int count = Integer.parseInt(sc.next());

        for(int i = 0; i < count; i++) {
            text = sc.next();
            listA.add(text);

        }
        List<String> listB = new ArrayList<String>(new HashSet<>(listA));
        System.out.print(listB.size());
    }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

}


import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[]args) {
        try {

         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

      HashSet<String> lottery = new HashSet<String>();
      for(int i = 0;i<n;i++) {
          String words = br.readLine();
          lottery.add(words);
      }
System.out.println(lottery.size());

        }catch(Exception e) {
        }
    }

}


import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) {

        FastScanner fs = new FastScanner();

        int n = fs.nextInt();
        String[] ss = new String[n];
        HashSet<String> hash = new HashSet<>();
        for( int i = 0 ; i < n ; i++ ){
            ss[i] = fs.next();
            hash.add( ss[i] );
        }
        System.out.println(hash.size());
    }

    static class FastScanner {
        private final InputStream in = System.in;
        private final byte[] buffer = new byte[1024];
        private int ptr = 0;
        private int bufferLength = 0;

        private boolean hasNextByte() {
            if (ptr < bufferLength) {
                return true;
            } else {
                ptr = 0;
                try {
                    bufferLength = in.read(buffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bufferLength > 0;
            }
        }

        private int readByte() {
            if (hasNextByte()) {
                return buffer[ptr++];
            } else {
                return -1;
            }
        }

        private static boolean isPrintableChar(int c) {
            return 33 <= c && c <= 126;
        }

        boolean hasNext() {
            while (hasNextByte() && !isPrintableChar(buffer[ptr])) {
                ptr++;
            }
            return hasNextByte();
        }

        String next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            StringBuilder sb = new StringBuilder();
            int b = readByte();
            while (isPrintableChar(b)) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        long nextLong() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            long n = 0;
            boolean minus = false;
            int b = readByte();
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            if (b < '0' || '9' < b) {
                throw new NumberFormatException();
            }
            while (true) {
                if ('0' <= b && b <= '9') {
                    n *= 10;
                    n += b - '0';
                } else if (b == -1 || !isPrintableChar(b)) {
                    return minus ? -n : n;
                } else {
                    throw new NumberFormatException();
                }
                b = readByte();
            }
        }

        public int nextInt() {
            long nl = nextLong();
            if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) {
                throw new NumberFormatException();
            }
            return (int) nl;
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }

    private static int gcd( int a , int b ){
        int x;
        int y;
        if (a > b) {
            x = a;
            y = b;
        } else {
            x = b;
            y = a;
        }
        int tmp;
        while ((tmp = x % y) != 0) {
            x = y;
            y = tmp;
        }
        return y;
    }

}


import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	static PrintStream o = System.out;

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		String[] get = new String[n];
		int res = 0;
		sc.nextLine();
		for (int i = 0; i < n; i++) {
			String one = sc.nextLine();
			boolean find = false;
			for (int j = 0; j < res; j++) {
				if (one.equals(get[j])) {
					find = true;
					break;
				}
			}
			if (!find) {
				get[res] = one;
				res++;
			}
		}
		o.println(res);
	}
}


import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	static PrintStream o = System.out;

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		ArrayList<String> get = new ArrayList<String>();
		int res = 0;
		sc.nextLine();
		for (int i = 0; i < n; i++) {
			String one = sc.nextLine();
			boolean find = false;
			for (String string : get) {
				if (string.equals(one)) {
					find = true;
					break;
				}
			}
			if (!find) {
				get.add(one);
				res++;
			}
		}
		o.println(res);
	}
}


import java.util.ArrayList;
import java.util.Scanner;
public class Main {
    public static void main(String[] args){

    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    ArrayList<String>ans  = new ArrayList<>();

    for(int i=0; i<n; i++) {
    	String s = sc.next();
    	if(!ans.contains(s)){
    	      ans.add(s);
    	}
    }
    	System.out.println(ans.size());
      }
}


#pragma GCC optimize ("Ofast")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

void pakuri_sort(int N, ll A[]) {
	const int b = 8;
	ll tmp[200001];
	rep(k, 4) {
		int kazu[1 << b] = {}, kazu2[1 << b] = {};
		rep(i, N) kazu[A[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu[i + 1] += kazu[i];
		for (int i = N - 1; i >= 0; i--) tmp[--kazu[A[i] >> k * b & ((1 << b) - 1)]] = A[i];
		k++;
		rep(i, N) kazu2[tmp[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu2[i + 1] += kazu2[i];
		for (int i = N - 1; i >= 0; i--) A[--kazu2[tmp[i] >> k * b & ((1 << b) - 1)]] = tmp[i];
	}
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	ll S[200000];
	int N = 0;
	char c;
	while ((c = getchar_unlocked()) >= '0') N = N * 10 + c - '0';

	rep(i, N) {
		ll s = 1;
		while ((c = getchar_unlocked()) >= 'a') s = s * 26 + c - 'a';
		S[i] = s;
	}

	pakuri_sort(N, S);

	int kotae = 0;
	ll mae = -1;
	rep(i, N) {
		if (mae != S[i]) {
			kotae++;
			mae = S[i];
		}
	}

	printf("%d\n", kotae);

	Would you please return 0;
}


#pragma GCC optimize ("Ofast")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

void pakuri_sort(int N, ll A[]) {
	const int b = 12;
	ll tmp[200001];
	rep(k, 4) {
		int kazu[1 << b] = {}, kazu2[1 << b] = {};
		rep(i, N) kazu[A[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu[i + 1] += kazu[i];
		for (int i = N - 1; i >= 0; i--) tmp[--kazu[A[i] >> k * b & ((1 << b) - 1)]] = A[i];
		k++;
		rep(i, N) kazu2[tmp[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu2[i + 1] += kazu2[i];
		for (int i = N - 1; i >= 0; i--) A[--kazu2[tmp[i] >> k * b & ((1 << b) - 1)]] = tmp[i];
	}
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	ll S[200000];
	int N = 0;
	char c;
	while ((c = getchar_unlocked()) >= '0') N = N * 10 + c - '0';

	rep(i, N) {
		ll s = 1;
		while ((c = getchar_unlocked()) >= 'a') s = s * 26 + c - 'a';
		S[i] = s;
	}

	pakuri_sort(N, S);

	int kotae = 0;
	ll mae = -1;
	rep(i, N) {
		if (mae != S[i]) {
			kotae++;
			mae = S[i];
		}
	}

	printf("%d\n", kotae);

	Would you please return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int  long long int
#define fi first
#define se second
#define pb push_back
#define soo(v) sort(v.rbegin(),v.rend())
#define so(v) sort(v.begin(),v.end())
#define lb(v,x) lower_bound(v.begin(),v.end(),x)
#define ub(v,x) upper_bound(v.begin(),v.end(),x)
#define endl '\n'
#define dbv(v) cout<<endl;cout<<#v<<"-->> ";for(auto it:v){cout<<it<<" ";}cout<<endl;
#define dbm(m)cout<<endl;cout<<#m<<"-->> ";for(auto it:m){cout<<it.fi<<" "<<it.se.fi<<" "<<it.se.se<<endl;}
#define dbs(s)cout<<endl;cout<<#s<<"-->> ";for(auto it:s){cout<<it<<" ";}cout<<endl;
#define mod 1000000007
#define db1(x) cout<<#x<<"="<<x<<endl;
#define db2(x,y) cout<<#x<<"="<<x<<","<<#y<<"="<<y<<endl;
#define db3(x,y,z) cout<<#x<<"="<<x<<","<<#y<<"="<<y<<","<<#z<<"="<<z<<endl;
#define mx 1e18
#define mxe(v) *max_element(v.begin(),v.end())
#define mne(v)  *min_element(v.begin(),v.end())
#define double long double
#define re(s) reverse(s.begin(),s.end())
#define io std::ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL);
int powe(int x,int n)
{
  if(n==0)return 1;
  if(n%2==0)
    return powe((x%mod*x%mod)%mod,n/2)%mod;
  return (x%mod*powe((x%mod*x%mod)%mod,(n-1)/2))%mod;
}
int gcd(int A,int B)
{
  if(B==0)return A;
  return gcd(B,A%B);
}

int32_t main()
{
  io
  int n;
  cin>>n;
  map<string,int>mm;string ss;
  for(int i=0;i<,n;i++){cin>>ss;mm[ss]++;}
    cout<<mm.size()<<endl;

}


#include <bits/stdc++.h>
using namespace std;
string a[100005];
long long n,k;

int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=0;i<=n;i++){
        if(a[i]!=a[i+1])k++;
    }
    cout<<k;
    return 0;}


#include <bits/stdc++.h>
using namespace std;
string a[100005];
long long n,k;

int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=0;i<n;i++){
        if(a[i]!=a[i+1])k++;
    }
    cout<<k;
    return 0;}


#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
uint32_t nextstr(char *s){ char c=getchar_unlocked(); while(c==' '||c=='\n') c=getchar_unlocked(); uint32_t len=0; while(c!=' '&&c!='\n'){ *s++=c; len++; c=getchar_unlocked(); } *s='\0'; return len; }
void printint(uint32_t x){ if(x<0){x=-x; putchar_unlocked('-');}else if(x==0){putchar_unlocked('0');} int d=0; char s[10]; while(x){ s[d]='0'+x%10; x/=10; d++; } for (int i=d-1; i>=0; i--) putchar_unlocked(s[i]); putchar_unlocked('\n'); }
void rsort_str(void *base, const int count, const int size);

char str[200000][11];

int main(void){
	uint32_t n=nextpint();
	for(uint32_t i=0; i<n; i++){
		nextstr(str[i]);
	}
	rsort_str(str, n, 11);
	uint32_t ans=1;
	for(uint32_t i=1; i<n; i++){
		if(strcmp(str[i], str[i-1])) ans++;
	}
	printint(ans);
}

void rsort_str(void *base, const int count, const int size){
	char (*a)[size]=base;
	char (*b)[size]=malloc(count*size);
	int c[0x100];
	for(int j=size-1; j>=0; j--){
		memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[a[i][j]]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ memcpy(&b[--c[a[i][j]]], a[i], size); }{void *t=a; a=b; b=t;}
	}
	if((size&1)==0){
		free(b);
	}else{
		memcpy(b, a, count*size);
		free(a);
	}
}


#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
void printint(uint32_t x){ if(x<0){x=-x; putchar_unlocked('-');}else if(x==0){putchar_unlocked('0');} int d=0; char s[10]; while(x){ s[d]='0'+x%10; x/=10; d++; } for (int i=d-1; i>=0; i--) putchar_unlocked(s[i]); putchar_unlocked('\n'); }
void rsort_str(void *base, const int count, const int size);

char str[200000][11];

int main(void){
	uint32_t n=nextpint();
	for(uint32_t i=0; i<n; i++){
		char *s=str[i];
		char c=getchar_unlocked();
		while(c!=' '&&c!='\n'){ *s++=c; c=getchar_unlocked(); }
		*s='\0';
	}
	rsort_str(str, n, 11);
	uint32_t ans=1;
	for(uint32_t i=1; i<n; i++){
		if(strcmp(str[i], str[i-1])) ans++;
	}
	printint(ans);
}

void rsort_str(void *base, const int count, const int size){
	char (*a)[size]=base;
	char (*b)[size]=malloc(count*size);
	int c[0x100];
	for(int j=9; j>=0; j--){
		memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[a[i][j]]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ memcpy(&b[--c[a[i][j]]], a[i], size); }{void *t=a; a=b; b=t;}
	}
	free(b);
}


#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
uint32_t nextstr(char *s){ char c=getchar_unlocked(); while(c==' '||c=='\n') c=getchar_unlocked(); uint32_t len=0; while(c!=' '&&c!='\n'){ *s++=c; len++; c=getchar_unlocked(); } *s='\0'; return len; }
void printint(uint32_t x){ if(x<0){x=-x; putchar_unlocked('-');}else if(x==0){putchar_unlocked('0');} int d=0; char s[10]; while(x){ s[d]='0'+x%10; x/=10; d++; } for (int i=d-1; i>=0; i--) putchar_unlocked(s[i]); putchar_unlocked('\n'); }
void rsort_str(void *base, const int count, const int size);

char str[200000][11];

int main(void){
	uint32_t n=nextpint();
	for(uint32_t i=0; i<n; i++){
		nextstr(str[i]);
	}
	rsort_str(str, n, 11);
	uint32_t ans=1;
	for(uint32_t i=1; i<n; i++){
		if(strcmp(str[i], str[i-1])) ans++;
	}
	printint(ans);
}

void rsort_str(void *base, const int count, const int size){
	char (*a)[size]=base;
	char (*b)[size]=malloc(count*size);
	int c[0x100];
	for(int j=9; j>=0; j--){
		memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[a[i][j]]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ memcpy(&b[--c[a[i][j]]], a[i], size); }{void *t=a; a=b; b=t;}
	}
	free(b);
}


#include<stdio.h>

int main(void){
  int j=1,N,count=0;
  char s[][10];
  scanf("%d",&N);
  for(int i=0;i<N;i++)
    scanf("%s",s[i]);

  for(int k=j-1;k<N-1;k++){
    for(j;j<N,j++){
      if(s[k]==s[j])
        count++;
    }
    j=k+2;
  }
  printf("%d\n",count);

  return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>
#define FOR(i,n) for(int i=0;i<n;i++)
#define PRN(n) printf("%d\n",n)
#define PRF(n) printf("%lf\n",n)
#define PRL(n) printf("%lld\n",n)
#define PRS(s) printf("%s\n",s)
#define PRC(c) printf("%c",c)
#define INI(n) scanf("%d",&n)
#define INL(n) scanf("%lld",&n)
#define INF 10000000000
#define mod 1000000007
#define X 100000
#define N 20
#define M 46
typedef long long int ll;
ll finv[X];
ll fac[X];
ll inv[X];
ll usort(const void *a, const void *b){return *(ll*)a-*(ll*)b;}
ll dsort(const void *a, const void *b){return *(ll*)b-*(ll*)a;}
ll ssort(const void *a, const void *b){return strcmp((char*)a,(char*)b);}
void Iswap(int *a,int *b){
  int t=*a;
  *a=*b;
  *b=t;
}
void Fswap(double *a,double *b){
  double t=*a;
  *a=*b;
  *b=t;
}
void Lswap(ll *a,ll *b){
  ll t=*a;
  *a=*b;
  *b=t;
}
ll min(ll a,ll b){
  if(a>b)return b;
  return a;
}
ll max(ll a,ll b){
  if(a>b)return a;
  return b;
}
ll z(ll a){return max(a,-a);}
ll gcd(ll a,ll b){if(!b){return a;}else{return gcd(b,a%b);}}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll kt(ll a){
  ll sum=0;
  while(a){
    a/=10;
    sum++;
  }
  return sum;
}
ll ks(ll a){
  ll sum=0;
  while(a){
    sum+=a%10;
    a/=10;
  }
  return sum;
}
void nCrReady(){
  fac[0]=fac[1]=1;
  finv[0]=finv[1]=1;
  inv[1]=1;
  for (ll i=2;i<X;i++){
    fac[i]=fac[i-1]*i%mod;
    inv[i]=mod-inv[mod%i]*(mod/i)%mod;
    finv[i]=finv[i-1]*inv[i]%mod;
  }
}
ll nCr(ll n,ll k){return fac[n]*(finv[k]*finv[n-k]%mod)%mod;}
ll modpow(ll a,ll n){
  ll res=1;
  while(n>0){
    if(n&1)res=res*a%mod;
    a=a*a%mod;
    n>>=1;
  }
  return res;
}
int main(void){
  int n;
  INI(n);
  char s[n][200001];
  FOR(i,n)scanf("%s",s[i]);
  qsort(s,n,sizeof(s[0]),ssort);
  int ans=1;
  FOR(i,n-1){
    if(strcmp(s[i],s[i+1])){
      ans++;
    }
  }
  PRN(ans);
  return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int		g_node_count = 0;

typedef	struct	s_btree
{
	char			*item;
	struct s_btree	*left;
	struct s_btree	*right;
}					t_btree;

t_btree	*btree_create_element(void *str)
{
	t_btree	*ret;

	ret = malloc(sizeof(t_btree));
	ret->item = str;
	ret->left = 0;
	ret->right = 0;
	return (ret);
}

int		btree_search_item(t_btree *root, void *item)
{
	int	ret;

	if (!root)
		return (0);
	if ((ret = btree_search_item(root->left, item)))
		return (ret);
	if (!strcmp(root->item, item))
		return (1);
	if ((ret = btree_search_item(root->right, item)))
		return (ret);
	return (0);
}

void	btree_insert_item(t_btree **root, void *item)
{
	if (!*root)
	{
		*root = btree_create_element(item);
		return ;
	}
	if (strcmp((*root)->item, item) < 0)
	{
		if (!(*root)->left)
		{
			(*root)->left = btree_create_element(item);
			return ;
		}
		btree_insert_item(&(*root)->left, item);
	}
	else
	{
		if (!(*root)->right)
		{
			(*root)->right = btree_create_element(item);
			return ;
		}
		btree_insert_item(&(*root)->right, item);
	}
}

void	btree_count_node(t_btree *root)
{
	if (root->left)
		btree_count_node(root->left);
	g_node_count++;
	if (root->right)
		btree_count_node(root->right);
}

int		main(void)
{
	int		N;
	int		i;
	char	(*S)[11];
	t_btree	*tree;

	scanf("%d", &N);
	S = malloc(sizeof(char) * N * 11);
	for (i = 0; i < N; i++)
		scanf("%s", S[i]);
	tree = 0;
	for (i = 0; i < N; i++)
	{
		if (!btree_search_item(tree, S[i]))
			btree_insert_item(&tree, S[i]);
	}
	btree_count_node(tree);
	printf("%d\n", g_node_count);
	return (0);
}


'use strict';
const main = arg => {
  const input = arg.trim().split('\n');

  const setItems = new Set(input);
  console.log(setItems.size - 1);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


let input = require('fs').readFileSync('/dev/stdin', 'utf8')
.split(/\n| /)
// .map(item => parseInt(item))
.slice(1,-1)

console.log([...new Set(input)].length)


function main(input) {
    const arr = input.trim().split('\n');
    const set = new Set(arr.slice(1))
    console.log(set.size)
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'))


function Main(input) {
  input=input.split("\n");

  const N=input[0]-0;
  var ret=0;
  var array=[];
  for(var i=1;i<input.length;i++){
    if(!array.includes(input[i])){
      array.push(input[i]);
      ret++;
    }
  }
  console.log(ret);
}

//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict'

const main = (INPUT) => {
  const input = INPUT.split('\n')
  console.log(new Set(input.slice(1)).size)
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'))


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var (
	scanner = bufio.NewScanner(os.Stdin)
)

// nextLine は次の行を受け取り、文字列として返す関数
func nextLine() string {
	scanner.Scan()
	return scanner.Text()
}

// nextLineInt は次の行を受け取り、int型として返す関数
func nextLineInt() int {
	scanner.Scan()
	num, err := strconv.Atoi(scanner.Text())
	if err != nil {
		panic(err)
	}
	return num
}

func main() {
	// 1行を取得してint型に変換されたものをnに代入
	var lotteryNum int = nextLineInt()
	// string: int のマップをNの分だけ作成
	var lotteryKinds map[string]int = make(map[string]int, lotteryNum)

	for i := 1; i <= lotteryNum; i++ {
		var lotteryPrize string = nextLine()
		if _, state := lotteryKinds[lotteryPrize]; !state {
			lotteryKinds[lotteryPrize] = 1
		}
	}

	fmt.Println(len(lotteryKinds))
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func main() {
	n := nextInt()
	var m = make(map[string]int, n)
	for _, str := range nextStrings(n) {
		m[str] = 1
	}

	count := 0
	for _, val := range m {
		count = count + val
	}

	fmt.Printf("%d\n", count)
}

func nextStrings(n int) []string {
	ret := make([]string, n)
	for i := 0; i < n; i++ {
		ret[i] = next()
	}
	return ret
}

func nextInt() int {
	a, _ := strconv.Atoi(next())
	return a
}

func next() string {
	sc.Scan()
	return sc.Text()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	n := nextInt()
	s := make(map[string]int, n)

	for i := 1; i <= n; i++ {
		k := nextLine()
		if _, ok := s[k]; !ok {
			s[k] = 1
		} else {
			s[k] += 1
		}
	}

	fmt.Println(len(s))
}

// =================================
// I/O util
// =================================

var sc = bufio.NewScanner(os.Stdin)

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

// =================================


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

/*-----------Main-----------*/

func main() {
	n := readI()
	s := readSs(n)

	fmt.Println(len(unique(s)))
}

func unique(a []string) []string {
	u := make([]string, 0, len(a))
	for _, v := range a {
		if !isContain(u, v) {
			u = append(u, v)
		}
	}
	return u
}

func isContain(a []string, b string) bool {
	for _, v := range a {
		if v == b {
			return true
		}
	}
	return false
}

/*-----------Utilities-----------*/

var sc = bufio.NewScanner(os.Stdin)

func init() {
	if len(os.Args) >= 2 {
		if os.Args[1] == "debug" {
			debug()
		}
	}
	const maxBuf = 200100
	var buf []byte = make([]byte, maxBuf)
	sc.Split(bufio.ScanWords)
	sc.Buffer(buf, maxBuf)
}

func debug() {
	testFile, err := os.Open("./test/sample-1.in")
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error : There is no testfile.")
		os.Exit(1)
	}
	sc = bufio.NewScanner(testFile)
}

func readS() string {
	sc.Scan()
	return sc.Text()
}

func readSs(a int) []string {
	b := make([]string, a)
	for i := 0; i < a; i++ {
		b[i] = readS()
	}
	return b
}

func readI() int {
	sc.Scan()
	r, _ := strconv.Atoi(sc.Text())
	return r
}

func readIs(a int) []int {
	b := make([]int, a)
	for i := 0; i < a; i++ {
		b[i] = readI()
	}
	return b
}

func readF() float64 {
	sc.Scan()
	r, _ := strconv.ParseFloat(sc.Text(), 64)
	return r
}

func readFs(a int) []float64 {
	b := make([]float64, a)
	for i := 0; i < a; i++ {
		b[i] = readF()
	}
	return b
}

func max(a []int) int {
	l := len(a)
	m := a[0]
	for i := 1; i < l; i++ {
		if a[i] > m {
			m = a[i]
		}
	}
	return m
}

func min(a []int) int {
	l := len(a)
	m := a[0]
	for i := 1; i < l; i++ {
		if a[i] < m {
			m = a[i]
		}
	}
	return m
}

func sortI(a []int) []int {
	sort.Ints(a)
	return a
}

func reverse(a []int) []int {
	l := len(a)
	r := make([]int, l)
	for i := 0; i < l; i++ {
		r[i] = a[l-i-1]
	}
	return r
}

func countI(a []int, b int) int {
	l := len(a)
	var c int
	for i := 0; i < l; i++ {
		if a[i] == b {
			c++
		}
	}
	return c
}


package main

import "fmt"

func main() {
	var a,b,c,d int
	fmt.Scan(&a, &b, &c, &d)
	if (a+d-1)/d >= (c+b-1)/b {
		fmt.Println("Yes")
	} else {
		fmt.Println("No")
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanInit()
	n := scanInt()
	lottery := map[string]bool{}
	count := 0
	for i:= 0; i<n; i++ {
		s := scan()
		if _,ok := lottery[s]; !ok {
			lottery[s] = true
			count ++
		}
	}
	fmt.Println(count)
}
var sc = bufio.NewScanner(os.Stdin)
func scanInit () {
	sc.Split(bufio.ScanWords)
}
func scanInt () int{
sc.Scan()
	i,_ := strconv.Atoi(sc.Text())
	return i
}
func scan () string{
	return sc.Text()
}


puts $<.read.split.drop(1).uniq.count


puts readlines.uniq.size - 1


n = gets.split.map(&:to_i)
array = readlines.map(&:chomp!)

puts array.uniq.size


n = gets.to_i

items = []
n.times do
  items.push gets.chomp
end

puts items.uniq


n = gets.to_i

items = []
n.times do
  items << gets
end

puts items.uniq


use std::io::{stdin, Read};

fn main() {
    let mut buf = String::new();
    stdin().read_to_string(&mut buf).unwrap();
    let s: std::collections::HashSet<&str> = buf.split_whitespace().collect();
    println!("{}", s.len() - 1)
}


use std::collections::HashSet;
use std::io::Read;

fn main() {
    let mut line = String::new();
    std::io::stdin().read_to_string(&mut line);
    let mut tok = line.split_whitespace();
    let mut n: usize = tok.next().unwrap().parse().unwrap();
    let mut r = HashSet::new();
    for _ in 0..n {
        r.insert(tok.next().unwrap());
    }
    println!("{}", r.len());
}


use proconio::{input, fastout};
use std::collections::HashSet;

#[fastout]
fn main() {
    input! {
        n: usize,
        sss: [String; n],
    }

    let uniq: HashSet<&String> = sss.iter().collect();
    println!("{:?}", uniq.len());
}


use proconio_derive::fastout;

#[fastout]
fn main() {
    proconio::input! {
        n: usize,
        mut s: [String;n]
    }
    let mut s: Vec<String> = s;
    s.sort();
    let mut ans = 0;
    let mut prv = String::new();
    for v in s {
        if prv != v {
            ans += 1;
        }
        prv = v;
    }
    println!("{}", ans);
}


use std::io::*; //Not mine.
use std::str::FromStr;
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}
use std::collections::HashSet;
fn main() {
    n: usize = read();
    s: HashSet<String> = HashSet::new();
    for i in 0..n {
        _s: String = read();
        s.insert(_s);
    }
    println!("{}", s.len());
}


const NUM_OF_AB :usize = 26;
const A_INDEX   :usize = 97;

struct Category {
    //depth    :u32,
    children    :Vec<Category>,
    list        :Vec<String>,
    active_bmp  :u32,
}
impl Category {
    //fn new(depth :u32) -> Category
    fn new() -> Category
    {
        Category {
            //depth:    depth,
            children:   Vec::new(),
            list:       Vec::new(),
            active_bmp: 0,
        }
    }

    fn prepare(&mut self)
    {
        for _ in 0..NUM_OF_AB {
            self.children.push(Category::new());
        }
    }

    fn is_active(&self, key1 :usize, _key2 :usize) -> bool
    {
        let mut ret = false;
        if  (self.active_bmp & (1<<key1)) != 0  {
            //if  (self.children[key1].active_bmp & (1<<key2)) != 0  {
                ret = true;
            //}
        }
        ret
    }

    fn activate(&mut self, key1 :usize, _key2 :usize)
    {
        if  (self.active_bmp & (1<<key1)) == 0  {
            self.children[key1].prepare();
            self.active_bmp |= {1<<key1};
        }
        //println!("len = {}", self.children[key1].children[key2].list.len());
    }

    fn search(&self, word :&String) -> bool
    {
        let mut ret = false;
        for i in 0..self.list.len() {
            if  *word == self.list[i]  {
                ret = true;
                break;
            }
        }
        ret
    }

    fn push(&mut self, word :String)
    {
        self.list.push(word);
    }

    fn num_of_nodes(&self) -> u32
    {
        let mut total :u32 = 0;
        for frst in 0..NUM_OF_AB {
            for scnd in 0..NUM_OF_AB {
                if  self.is_active(frst, scnd)  {
                    total += {self.children[frst].children[scnd].list.len() as u32};
                }
            }
        }
        total
    }
}

fn index_get(c :char) -> usize
{
    (c as usize) - A_INDEX
}

fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();

    let mut prize :Category = Category::new();
    prize.prepare();

    let num_of_prizes :usize = s.trim().parse::<usize>().ok().unwrap();

    for _ in 0..num_of_prizes {
        let mut s1 = String::new();
        std::io::stdin().read_line(&mut s1).ok();

        let mut si = s1.chars();
        let frst = index_get(si.next().unwrap());
        let scnd =
            match  si.next()  {
                None    => 0,
                Some(c) => index_get(c),
            };
        if  !prize.is_active(frst, scnd)  {
            prize.activate(frst, scnd);
        }
        if  !prize.children[frst].children[scnd].search(&s1)  {
            prize.children[frst].children[scnd].push(s1);
        }
    }

    println!("{}", prize.num_of_nodes());
}


let N: Int = Int(readLine()!)!
var S: [String] = (1...N).map { _ in readLine()! }
print(Set(S).count)


let N = Int(readLine()!)!
var S = Array(repeating: "", count: N)
for n in 0 ..< N {
    S[n] = readLine()!
}

print(Set(S).count)


import Foundation
let main: () = {
    let N = nextInt()
    let S = StringArray(N) { next() }
    let set = Set<String>(S)
    let ans = set.count
    print(ans)
}()

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
}

extension Array {
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}

class SimpleScanner {
    private var cnt = 0
    private var lines = [String]()
    private var fileName = ""
    private let file: FileHandle
    init(_ filename: String = "") {
        if !filename.isEmpty {
            fileName = filename
            file = FileHandle(forReadingAtPath: fileName)!
        } else {
            file = FileHandle.standardInput
        }
        let contentData = file.readDataToEndOfFile()
        let contentString = String(data: contentData, encoding: .utf8) ?? ""
        lines = contentString.split(separator: "\n").map { String($0) }
        cnt = -1
    }
    deinit {
        if !fileName.isEmpty {
            file.closeFile()
        }
    }
    func next() -> String { cnt += 1; return lines[cnt] }
    func nextInt() -> Int { Int(next())! }
    func nextDouble() -> Double { Double(next())! }
    func listOfString() -> [String] { next().split(separator: " ").map { String($0) } }
    func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
    func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
    func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
    func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }
}

struct RingArray<T> {
    private var array: [T?]
    init(_ size: Int) { self.array = [T?](repeating: nil, count: size) }
    init(_ source: [T]) { self.array = source }
    var count: Int { array.count }
    var indices: Range<Int> { array.indices }
    subscript(_ index: Int) -> T {
        get{ array[(index + array.count) % array.count]! }
        set (newValue) { array[(index + array.count) % array.count] = newValue }
    }
    func toOffsetArray(offset: Int) -> [T] {
        let tmp = array[offset % array.count ..< array.count] + array[0 ..< offset % array.count]
        return tmp.map { $0!}
    }
    func toArray() -> [T] { array.map { $0! } }
}


import Foundation

let a = Int(readLine()!)!
var k:[String] = []
for _ in 0 ..< a {
    let input_line: String = readLine()!
        k.append(input_line)
}
let orderedSet = NSOrderedSet(array: k)
let uniqueValues = orderedSet.array as! [String]
print(uniqueValues.count)


import Foundation

let a = Int(readLine()!)!
var k:[String] = []
for _ in 0 ..< a {
    let input_line: String = readLine()!
        k.append(input_line)
}
let orderedSet = NSOrderedSet(array: k)
let uniqueValues = orderedSet.array as! [String]
print(uniqueValues)


let a = Int(readLine()!)!
var k:[String] = []
for i in 0 ..< a {
    var input_line: String = readLine()!
        k.append(input_line)
}
let orderedSet = NSOrderedSet(array: k)
let uniqueValues = orderedSet.array as! [String]
print(uniqueValues)


import * as fs from 'fs';

namespace AtCoder.abc001 {

    export class Program {

        constructor(private readonly args: string[]) {
        }

        /**
         * in
         *
         * out
         *
         */
        main(this: Program): void {
            const n: number = +this.args[0];
            const set = new Set();
            for (let i = 1; i <= n; i++) set.add(this.args[i]);
            console.log(set.size);
        }
    }
}

const args: string[] = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
const prg: AtCoder.abc001.Program = new AtCoder.abc001.Program(args);
prg.main();


import * as fs from "fs";

const input = (fs.readFileSync("/dev/stdin", "utf8") as string).split("\n");
const n = +input[0];
const a = new Set();
for (let i = 0; i < n; i++) {
	a.add(input[i + 1]);
}

console.log(a.size);


import { count } from 'console';

process.stdin.resume();
process.stdin.setEncoding('utf8');

// 標準入力取込
let gInput = '';
process.stdin.on('data', (chunk) => (gInput += chunk));
process.stdin.on('end', () => main(gInput.split(/\r?\n/)));

// 解答
function main(inputs: string[]): void {
  const n = Number(inputs[0]);
  let hitList = new Set;

  for (let i = 1; i <= n; i++) {
    hitList.add(inputs[i]);
  }

  console.log(hitList.size);
}


import * as fs from 'fs'
import {debug} from '../../../util'

const input = fs.readFileSync('/dev/stdin', 'utf8').split('\n') // ['1', '2' , ...]
const output = (x: any) => console.log(x)
// debug(input)
const [N, ...S] = input
// debug(N)
// debug(S)

const set = new Set<string>()

S.map(s => {
    set.add(s)
})

output(set.size)


import * as fs from 'fs'
import {debug} from '../../../util'

const input = fs.readFileSync('/dev/stdin', 'utf8').split('\n') // ['1', '2' , ...]
const output = (x: any) => console.log(x)
// debug(input)
const [N, ...S] = input
// debug(N)
// debug(S)

const map = new Map<string, number>()

S.map(s => {
    const v = map.get(s)
    if (v !== undefined) {
        map.set(s, v + 1)
    } else {
        map.set(s, 0)
    }
})

// debug(map)
output(map.size)