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 C (GCC 5.4.1) (judge verdict: Runtime Error)

#include <stdio.h>

int r(char in);
void quick_sort (int array[], int left, int right);
int partition (int array[], int left, int right);
void swap (int *x,  int *y);

int main(){
    char s[100001] = {'0'};
    char t[100001] = {'0'};

    int ar_s[26] = {0};
    int ar_t[26] = {0};

    scanf("%s",&s);
    scanf("%s",&t);


    for (int i = 0; i < 100001; i++) {
        if (r(s[i]) != -1) {
            ar_s[r(s[i])]++;
        }
        if (r(t[i]) != -1) {
            ar_t[r(t[i])]++;
        }
    }

    quick_sort(ar_s,0,25);
    quick_sort(ar_t,0,25);

    for (int i = 0; i < 26; i++) {
        if (ar_s[i] != ar_t[i]) {
            printf("no");
            return 0;
        }
    }

    
    printf("yes");

    return 0; 
    
	
}

int r(char in){
    switch (in) {
        case 'a':
        return 0;
        case 'b':
        return 1;
        case 'c':
        return 2;
        case 'd':
        return 3;
        case 'e':
        return 4;
        case 'f':
        return 5;
        case 'g':
        return 6;
        case 'h':
        return 7;
        case 'i':
        return 8;
        case 'j':
        return 9;
        case 'k':
        return 10;
        case 'l':
        return 11;
        case 'm':
        return 12;
        case 'n':
        return 13;
        case 'o':
        return 14;
        case 'p':
        return 15;
        case 'q':
        return 16;
        case 'r':
        return 17;
        case 's':
        return 18;
        case 't':
        return 19;
        case 'u':
        return 20;
        case 'v':
        return 21;
        case 'w':
        return 22;
        case 'x':
        return 23;
        case 'y':
        return 24;
        case 'z':
        return 25;

        default:
        return -1;
    }

}



 
void swap (int *x,  int *y) {
  int temp;    // 値を一時保存する変数
 
  temp = *x;
  *x = *y;
  *y = temp;
}
 
int partition (int array[], int left, int right) {
  int i, j, pivot;
  i = left;
  j = right + 1;
  pivot = left;   // 先頭要素をpivotとする
 
  do {
    do { i++; } while (array[i] < array[pivot]);
    do { j--; } while (array[pivot] < array[j]);
    // pivotより小さいものを左へ、大きいものを右へ
    if (i < j) { swap(&array[i], &array[j]);}
  } while (i < j);
 
  swap(&array[pivot], &array[j]);   //pivotを更新
 
  return j;
}
 
/* クイックソート */
void quick_sort (int array[], int left, int right) {
  int pivot;
 
  if (left < right) {
    pivot = partition(array, left, right);
    quick_sort(array, left, pivot-1);   // pivotを境に再帰的にクイックソート
    quick_sort(array, pivot+1, right);
  }
}