//#pragma comment(linker, "/stack:200000000") //  (UNCOMMENT WHEN HAVING LOTS OF RECURSIONS)
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")  // $ (UNCOMMENT WHEN TRYING TO BRUTEFORCE WITH A LOT OF LOOPS)\

#include <bits/stdc++.h>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <ratio>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

#define int long long
#define ll long long
#define rep(i,a,b) for(int i=a;i<b;++i)
#define fre(i,a,b) for(int i=a;i<=b;i++)
#define rpe(i,a,b) for(i=a-1;i>=b;i--)
#define rp(i,n) rep(i,0,n)
#define fr(i,n) fre(i,1,n)
#define pb push_back
#define mp make_pair
#define endl "\n"
#define F first
#define S second
#define vi vector<int>
#define all(c) (c).begin(),(c).end()
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b)) / gcd((a),(b))
#define bc(n) __builtin_popcountll(n)
#define lps(v,x) (lower_bound(all(v),x)-v.begin())
#define ups(v,x) (upper_bound(all(v),x)-v.begin())

typedef long double ld;

typedef tree< int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update>
    ordered_set;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the iterator to kth largest element.(0-based)

#define TRACE
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << endl;}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<"  ";__f(comma+1, args...);}
#else
#define trace(...)
#endif

auto clk=clock();
const int inft = (1LL<<61) ;
const int inf = 5e18;
const int mod = 1e9+7;
const int mod1 = 998244353;

int modpow(int x,int n,int mod){x %= mod ; int res = 1; while(n>0){ if(n & 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res;}


signed main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin.exceptions(cin.failbit);
    srand(chrono::high_resolution_clock::now().time_since_epoch().count());
    cout<<fixed<<setprecision(10);
    #ifndef ONLINE_JUDGE
       //freopen("input.txt", "r", stdin);
       //freopen("output.txt", "w", stdout) ;
    #endif // ONLINE_JUDGE

    string s ;
    cin >> s ;

    set<char> st ;
    rp(i,4)
    {
        st.insert(s[i]) ;
    }

    if(st.size()==2)
    {
        cout << "Yes" ;
    }
    else
    {
        cout << "No" ;
    }

return 0 ;
}







Measured memory_bytes: 256