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)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
#![allow(unused_imports)]

//input
use proconio::input;
use proconio::marker::{Bytes, Chars};
//use std::io::Read;

//collections
//use std::collections::BTreeMap;
//use std::collections::BTreeSet;
use std::collections::HashMap;
//use std::collections::HashSet;
//use std::collections::VecDeque;
//use std::collections::BinaryHeap;

//use std::cmp::*;
use maplit::*;

fn main() {
    input! {
        s: Chars,
        t: Chars,
    }
    let n = s.len();

    let mut s_dic = hashmap![];
    let mut t_dic = hashmap![];

    let mut tn = vec![];
    let mut sn = vec![];

    for i in 0..n {
        if !s_dic.contains_key(&s[i]) {
            s_dic.insert(s[i], s_dic.len());
        }
    }
    for i in 0..n {
        if !t_dic.contains_key(&t[i]) {
            t_dic.insert(t[i], t_dic.len());
        }
    }

    for i in 0..n {
        sn.push(*s_dic.get(&s[i]).unwrap());
    }
    for i in 0..n {
        tn.push(*t_dic.get(&t[i]).unwrap());
    }

    if sn == tn {
        println!("Yes");
    } else {
        println!("No");
    }
}
*/

fn main() {
    let exe = "/tmp/binD96A1277";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";