Problem:
Score : 300 points

Problem Statement

You are given strings S and T consisting of lowercase English letters.

You can perform the following operation on S any number of times:

Operation: Choose two distinct lowercase English letters c_1 and c_2, then replace every occurrence of c_1 with c_2, and every occurrence of c_2 with c_1.

Determine if S and T can be made equal by performing the operation zero or more times.

Constraints

1 \leq |S| \leq 2 \times 10^5

|S| = |T|

S and T consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

S
T

Output

If S and T can be made equal, print Yes; otherwise, print No.

Sample Input 1

azzel
apple

Sample Output 1

Yes

azzel can be changed to apple, as follows:

Choose e as c_1 and l as c_2. azzel becomes azzle.

Choose z as c_1 and p as c_2. azzle becomes apple.

Sample Input 2

chokudai
redcoder

Sample Output 2

No

No sequences of operation can change chokudai to redcoder.

Sample Input 3

abcdefghijklmnopqrstuvwxyz
ibyhqfrekavclxjstdwgpzmonu

Sample Output 3

Yes

Solution in Rust (1.15.1) (judge verdict: Accepted)


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

pub 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::HashMap;

fn main() {
  let a = read::<String>();
  let b = read::<String>();

  let a_v = a.chars().collect::<Vec<char>>();
  let b_v = b.chars().collect::<Vec<char>>();

  if check(&a_v, &b_v) && check(&b_v, &a_v) {
    println!("Yes");
  } else {
    println!("No");
  }
}

fn check(a: &Vec<char>, b: &Vec<char>) -> bool {
  let mut map = HashMap::new();
  let mut result = true;

  for (i, v) in a.iter().enumerate() {
    let value = b[i];
    if map.contains_key(&v) {
      if *map.get(&v).unwrap() != value {
        result = false
      }
    } else {
      map.insert(v, value);
    }
  }
  result
}

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

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

// pub 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::HashMap;

// fn main() {
//   let a = read::<String>();
//   let b = read::<String>();

//   if check(&a, &b) && check(&b, &a) {
//     println!("Yes");
//   } else {
//     println!("No");
//   }

//   // println!("{}", max_v);
// }

// fn check(a: &str, b: &str) -> bool {
//   let mut map = HashMap::new();
//   let mut result = true;

//   for (i, v) in a.chars().enumerate() {
//     let value = b.chars().nth(i).unwrap();
//     if map.contains_key(&v) {
//       if *map.get(&v).unwrap() != value {
//         result = false
//       }
//     } else {
//       map.insert(v, value);
//     }
//   }
//   result
// }