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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Numerics;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class Solver
{
    string s, t;
    int n;
    public void Solve()
    {
        s = rs; t = rs;
        n = s.Length;
        bool[] d = new bool[26];
        bool[] e = new bool[26];
        bool b = true;
        for(int i = 0; i < n; i++)
        {
            if (!d[s[i] - 'a'])
            {
                b = b && !e[t[i] - 'a'] && search(s[i], t[i]);
                d[s[i] - 'a'] = true;
                e[t[i] - 'a'] = true;
            }
        }
        Yn(b);
    }

    bool search(char c1,char c2)
    {
        for(int i = 0; i < n; i++)
        {
            if (s[i] == c1)
            {
                if (t[i] != c2)
                {
                    return false;
                }
            }
        }
        return true;
    }

    int ri { get { return sc.Integer(); } }
    long rl { get { return sc.Long(); } }
    double rd { get { return sc.Double(); } }
    string rs { get { return sc.Scan(); } }
    public StreamScanner sc = new StreamScanner(Console.OpenStandardInput());

    private const long mod = 1000000007;
    long digit10(long n) { long p = 1; while (p <= n) { p *= 10; } return p % mod; }
    long abs(long n) { return (n > 0) ? n : -n; }
    long gcd(params long[] n) { long p = n[0]; for (long i = 1; i < n.Length; i++) { p = gcd(p, n[i]); } return p; }
    long gcd(long a, long b) { return (a == 0) ? b : gcd(b % a, a); }
    long lcm(params long[] n) { long p = n[0]; for (long i = 1; i < n.Length; i++) { p = lcm(p, n[i]); } return p; }
    long lcm(long a, long b) { return a * b / gcd(a, b); }
    long max(params long[] n) { long p = n[0]; for (long i = 1; i < n.Length; i++) { p = (p > n[i]) ? p : n[i]; } return p; }
    long min(params long[] n) { long p = n[0]; for (long i = 1; i < n.Length; i++) { p = (p < n[i]) ? p : n[i]; } return p; }
    void YN(bool t) { Console.WriteLine(t ? "YES" : "NO"); }
    void Yn(bool t) { Console.WriteLine(t ? "Yes" : "No"); }
    void yn(bool t) { Console.WriteLine(t ? "yes" : "no"); }
    string clip(string s, int start, int count)
    {
        if (start + count < s.Length) { s = s.Remove(start + count); }
        if (start > 0) { s = s.Remove(0, start); }
        return s;
    }
}

static class Program
{
    static public void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Solver();
        solver.Solve();
        Console.Out.Flush();
    }

    static BigInteger power(BigInteger b, BigInteger p)
    {
        BigInteger t = b;
        BigInteger q = 1;
        while (p > 0)
        {
            if (p % 2 == 1) q *= t;
            t *= t;
            p -= p % 2;
            p /= 2;
        }
        return q;
    }
}

public class StreamScanner
{
    public StreamScanner(Stream stream) { str = stream; }
    private readonly Stream str;
    private readonly byte[] buf = new byte[1024];
    private int len, ptr;
    public bool isEof = false;
    public bool IsEndOfStream { get { return isEof; } }
    private byte read()
    {
        if (isEof) throw new EndOfStreamException();
        if (ptr >= len)
        {
            ptr = 0;
            if ((len = str.Read(buf, 0, 1024)) <= 0)
            {
                isEof = true;
                return 0;
            }
        }
        return buf[ptr++];
    }
    public char Char()
    {
        byte b = 0;
        do b = read();
        while (b < 33 || 126 < b);
        return (char)b;
    }
    public string Scan()
    {
        var sb = new StringBuilder();
        for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
            sb.Append(b);
        return sb.ToString();
    }
    public long Long()
    {
        long ret = 0; byte b = 0; var ng = false;
        do b = read();
        while (b != '-' && (b < '0' || '9' < b));
        if (b == '-') { ng = true; b = read(); }
        for (; true; b = read())
        {
            if (b < '0' || '9' < b)
                return ng ? -ret : ret;
            else ret = ret * 10 + b - '0';
        }
    }
    public int Integer() { return (int)Long(); }
    public double Double() { return double.Parse(Scan()); }
}