#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
const int INF = 1e9 + 10;
int prime[MAXN];
int is[MAXN];
int cnt = 0;
struct Ac {
  int x, c;
};
vector<Ac> a1, a2;
int check(int a, int b) {
  int s = a + b;
  if (s % 3 != 0) return 0;
  if ((2 * a - b) % 3 != 0) return 0;
  if ((2 * b - a) % 3 != 0) return 0;
  if (a < b / 2 || b < a / 2) return 0;
  return 1;
}
set<long long> st;
int main() {
  for (int i = 0; i < MAXN; i++) {
    st.insert(1LL * i * i * i);
  }
  for (int i = 2; i < MAXN; i++) {
    if (!is[i]) {
      prime[cnt++] = i;
      if (1LL * i * i >= MAXN) continue;
      for (int j = i * i; j < MAXN; j += i) {
        is[j] = 1;
      }
    }
  }
  int n;
  scanf("%d", &n);
  while (n--) {
    a1.clear();
    a2.clear();
    int x, y;
    scanf("%d%d", &x, &y);
    long long ss = 1LL * x * y;
    if (st.count(ss) == 0) {
      puts("No");
      continue;
    }
    for (int i = 0; i < cnt; i++) {
      if (1LL * prime[i] * prime[i] > x) break;
      if (x % prime[i] == 0) {
        int c = 0;
        while (x % prime[i] == 0) {
          x /= prime[i];
          c++;
        }
        a1.push_back(Ac{prime[i], c});
      }
    }
    if (x > 1) a1.push_back(Ac{x, 1});
    for (int i = 0; i < cnt; i++) {
      if (1LL * prime[i] * prime[i] > y) break;
      if (y % prime[i] == 0) {
        int c = 0;
        while (y % prime[i] == 0) {
          y /= prime[i];
          c++;
        }
        a2.push_back(Ac{prime[i], c});
      }
    }
    if (y > 1) a2.push_back(Ac{y, 1});
    int a1l = a1.size(), a2l = a2.size();
    if (a1l != a2l) {
      puts("No");
      continue;
    }
    int flg = 1;
    for (int i = 0; i < a1l; i++) {
      if (a1[i].x != a2[i].x) {
        flg = 0;
        break;
      } else if (!check(a1[i].c, a2[i].c)) {
        flg = 0;
        break;
      }
    }
    if (flg)
      puts("Yes");
    else
      puts("No");
  }
  return 0;
}
