#include <bits/stdc++.h>

using namespace std;
inline void prep ()
{
  cin.tie (0);
  cin.sync_with_stdio (0);
};
//printf("%.12lf\n",mid);
// __builtin_popcount(int) count 1's in binary
// get decimal pert of number
/*
double intpart;
double thiss = modf((double)(n*m)/(double)k, &intpart);
*/
// round = (int)(num+.5)
int mod = 1000000007;

long long mymod(long long num){
  if (num< 0){
    if (mod == 1){
      return 0;
    }
    return (mod-abs(num)%mod)%mod;
  }else{
    return num%mod;
  }
}

double eps = .000000001; 


int main ()
{
  prep ();
  set<char> chars;
  string s;
  cin >> s;
  int cnts[300] = {0};
  for (int i=0; i<s.size(); i++){
      chars.insert(s[i]);
      cnts[s[i]]++;
  }
  if (chars.size() == 2){
      for (int i : s){
          if (cnts[i] != 2){
              cout << "No";
              return 0;
          }
      }
  }else{
      cout << "No";
      return 0;
  }
  cout << "Yes";
  return 0;
}
// in dp problems think: up until here, intervals, or "what if there's 1, 2, 3..."
// in math problems write out equations
// also in math problems to change multiplication/division to addition/subtraction use logs, add/subtract something to make the multiplication easier (like if it's 3*f(x)+2, change it to 3*(f(x)+1)-1)
// if checked the logic check for bugs (like sorting wrong way or not putting a break in a loop)
// if n is 10^7 try brute force if the operations are simple
// if can't do dp do brute force/greedy
// to save time don't copy maps/vectors into variables if it already exists
// if wrong on decimal problem, check if program rounds or if you can round to a certain amt of decimals
// if decimals too, if can subtract instead of divide
// in recursion looking math problems look at things from the point of view of both sides (the start and the end sections of the recursion)
// think about how many possible answers there are to the problem
// try to set the answer to the problem and see if it's possible (like w/ binary search)
// if it makes it easier use +1 indexing
// think twice when writing things down that you're going to use later
// for conversions think if you can compute them w/ only one conversion 
// if the problem involves two things moving at the same time, see if you can generalise it to just one thing moving (590/B) (1117/C)
// if nt think primes
// see if you can do a pattern of steps to achieve something (1148/C) (1119/C)
// if sub-interval requirements, try to reduce problem into prefix array problem (pairwise numbers) (1174/D)
// think from the end of the problem (if this is the result, what is an attribute of it?)
// if repeating action, if good for debugging use function
// read problems twice, think about problem, even if have solution keep thinking about a more optimal one
// for uva see constraints, check if have to use getline
// if permutations, see if you can just iterate over numbers (like if it's a perm of 10 numbers)
// for geom check if it could be on inside/outside if intersections
// stop just assuming things (like on the problem where you just thought that there couldn't be 3 2's because 3 is odd)
// obviously, check problems solved by users occasionally to see if you should switch problems
// if # of sols are small precalculate
// if question is asking to find an optimal place, don't focus on finding the place, use what other things they give you to precalculate it (593/B) (Uva rat attack)
// if a constraint looks purposely small try to use it
// if can, change vector<bool> to bitset
// if brute force, try meet in middle
// if using dfs and using visited, after visit node, mark as not visited and keep vis global
// if it's one of those creative problems, try to make the most/least possible, try to use very small example to prove things
// what are we forced to do because of the problem's constraints? (like if it's graph and 1s time lim, is probably only 1 traverse of dfs and not n)
// if greedy, look at an observation like "they have to be as far out as they can" or "it's optimal to always put them here" for example
// if you think about binary search, don't just drop the idea quickly
// if it's a minutes/seconds question, convert everything to seconds
// try to avoid decimals
// for bisection don't use a last good variable
// if it's one of those problems where there's a lot of cases, go through the code again and see if there's a scenario you didn't think of
// if trying to maximize something, before categorizing/matching positives/negatives or evens/odds try only sorting
// when trying to find bugs, don't try input, look at code
// try not to categorize things (ex: if it's in front of this, it's this, and if it's in back of this, it's that)
// for simulation problems, to make it easier, see if you can use set to see if something's there
// if interval prob, also think about intervals instead of prefix array
// avoid division at all costs
// max 2d sum => n^3 = iterate through columns + greedy
// if trying to find optimal way to move something, try looking at things you aren't moving
// initializing list is linear
// brute force subsequence => queue
// if dp + order doesn't matter + limit on different kinds, put the different kinds in separate bins
// if dp, work through recursive and check for logic flaws and places where something could surpass array size
// for ceil, be careful if you think it's an int but it has a little decimal left
// write neater, don't do long lines
// with "coin change" dp try to avoid ind (it creates more edge cases). plus, don't assume you have an infinite amt of everything

Measured memory_bytes: 256