#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
using namespace std;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
const int INF = (1 << 30) - 1;
const long long INFL = 1LL << 60;
const long long mod = 998244353;
struct Segment_tree {
  using T = string;
  int n;
  vector<T> data;
  inline T vmerge(T l, T r) {
    if (l < r)
      return l + r;
    else
      return r + l;
  }
  Segment_tree(int n) : n(n) { data.assign(2 * n, ""); }
  void init(vector<string> s) {
    for (int i = 0; i < int(n); i++) {
      data[i + n] = s[i];
    }
    for (int i = n - 1; i >= 0; i--) {
      data[i] = vmerge(data[i * 2], data[i * 2 + 1]);
    }
  }
  T query() { return data[0]; }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  string s, t;
  cin >> s >> t;
  int n = s.size();
  int cnt = 1;
  int m = n;
  while (m % 2 == 0) {
    m /= 2;
    cnt *= 2;
  }
  vector<string> a(cnt);
  vector<string> b(cnt);
  m = n / cnt;
  for (int i = 0; i < int(cnt); i++) {
    a[i] = s.substr(i * m, m);
    b[i] = t.substr(i * m, m);
  }
  Segment_tree c(cnt);
  Segment_tree d(cnt);
  c.init(a);
  d.init(b);
  if (c.query() != d.query()) {
    cout << "NO" << endl;
  } else
    cout << "YES" << endl;
}
