#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

unordered_map<ll, ll> m;

int main()
{
    for (ll i = 2; i <= 1e6; i++) {
        ll s = i * i * i;
        m[s] = i;
    }

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

        ll c = a * b;
        auto it = m.find(c);
        if (it == m.end()) { cout << "No" << "\n"; continue; }

        ll no = 0;
        if (a % it->Y != 0) no = 1;
        if (b % it->Y != 0) no = 1;

        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<ll> primeFactors(ll N) {
    vector<ll> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<ll> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

//        ll c = a * b;
//        vector<mp> fc = getFactors(c);
//        ll no = 0;
//        for (ull i = 0; i < fc.size(); i++) {
//            if (fc[i].Y % 3 != 0) { no = 1; break; }
//        }
//        if (no) { cout << "No" << "\n"; continue; }

        ///////////////////////////////////////

        //if (a < b) { ll t = a; a = b; b = t; }

        ll no = 0;
        ll PF_idx = 0, PF = primes[PF_idx];
        while (PF * PF <= a) {
            ll cnta = 0, cntb = 0;
            while (a % PF == 0) { a /= PF; cnta++; }
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; break; }
            if (cntb > 0 && cnta == 0) { no = 1; break; }

            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

            PF = primes[++PF_idx];
        }
        if (!no && a != 1) {
            PF = a;
            ll cnta = 0, cntb = 0;
            while (a % PF == 0) { a /= PF; cnta++; }
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; }
            if (cntb > 0 && cnta == 0) { no = 1; }
            if ((cnta + cntb) % 3 != 0) {no = 1; }
        }

        if (!no && b != 1) {
            PF = b;
            ll cnta = 0, cntb = 0;
            while (a % PF == 0) { a /= PF; cnta++; }
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; }
            if (cntb > 0 && cnta == 0) { no = 1; }
            if ((cnta + cntb) % 3 != 0) {no = 1; }
        }

        if (no) { cout << "No" << "\n"; continue; }
            /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);
//        vector<mp> fb = primeFactors2(b);

//        //pr_vars(fa);
//        //pr_vars(fb);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;
         /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);

//        ll no = 0;
//        for (ull i = 0; i < fa.size(); i++) {
//            ll PF = fa[i].X;
//            ll cnta = fa[i].Y;
//            ll cntb = 0;
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }
//        }

//        if (b != 1) { no = 1; }

//        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<int, int>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<int> primeFactors(ll N) {
    vector<int> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<int> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }

        if (a < b) { ll t = a; a = b; b = t; }

        ll no = 0;
        ll PF_idx = 0, PF = primes[PF_idx];
        while (PF * PF <= a) {
        //while (PF <= a) {
            ll cnta = 0, cntb = 0;
            while (a % PF == 0) { a /= PF; cnta++; }
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; break; }
            if (cntb > 0 && cnta == 0) { no = 1; break; }

            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

            PF = primes[++PF_idx];
        }
        if (a != 1 && b != 1) { no = 1; }

        if (no) { cout << "No" << "\n"; continue; }

//        vector<mp> fa = getFactors(a);
//        vector<mp> fb = getFactors(b);

//        //pr_vars(fa);
//        //pr_vars(fb);
//        pr_vars(a, b);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<ll> primeFactors(ll N) {
    vector<ll> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<ll> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

//        ll c = a * b;
//        vector<mp> fc = getFactors(c);
//        ll no = 0;
//        for (ull i = 0; i < fc.size(); i++) {
//            if (fc[i].Y % 3 != 0) { no = 1; break; }
//        }
//        if (no) { cout << "No" << "\n"; continue; }

        ///////////////////////////////////////

//        if (a < b) { ll t = a; a = b; b = t; }

//        ll no = 0;
//        ll PF_idx = 0, PF = primes[PF_idx];
//        while (PF * PF <= a) {
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

//            PF = primes[++PF_idx];
//        }
//        if (a != 1) {
//            ll cnta = 1, cntb = 0;
//            while (b % a == 0) { b /= a; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; }
//            if (cntb > 0 && cnta == 0) { no = 1; }
//            if ((cnta + cntb) % 3 != 0) {no = 1; }
//        }

//        if (no) { cout << "No" << "\n"; continue; }
            /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);
//        vector<mp> fb = primeFactors2(b);

//        //pr_vars(fa);
//        //pr_vars(fb);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;
         /////////////////////////////////////////////

        vector<mp> fa = primeFactors2(a);

        ll no = 0;
        for (ull i = 0; i < fa.size(); i++) {
            ll PF = fa[i].X;
            ll cnta = fa[i].Y;
            ll cntb = 0;
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; break; }
            if (cntb > 0 && cnta == 0) { no = 1; break; }

            if ((cnta + cntb) % 3 != 0) {no = 1; break; }
        }

        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

map<ll, ll> m;

int main()
{
    for (ll i = 2; i <= 1e6; i++) {
        ll s = i * i * i;
        m[s] = i;
    }

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

        ll c = a * b;
        auto it = m.find(c);
        if (it == m.end()) { cout << "No" << "\n"; continue; }

        ll no = 0;
        if (a % it->Y != 0) no = 1;
        if (b % it->Y != 0) no = 1;

        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<int, int>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<int> primeFactors(ll N) {
    vector<int> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<int> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }

//        if (a < b) { ll t = a; a = b; b = t; }

//        ll no = 0;
//        ll PF_idx = 0, PF = primes[PF_idx];
//        while (PF * PF <= a) {
//        //while (PF <= a) {
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

//            PF = primes[++PF_idx];
//        }
//        if (a != 1 && b != 1) { no = 1; }

//        if (no) { cout << "No" << "\n"; continue; }

        vector<mp> fa = primeFactors2(a);
        vector<mp> fb = primeFactors2(b);

        //vector<mp> fa = getFactors(a);
        //vector<mp> fb = getFactors(b);

        pr_vars(fa);
        pr_vars(fb);

        ll n = 0;
        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
        for (ull i = 0; i < fa.size(); i++) {
            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
            ll cnt = fa[i].Y + fb[i].Y;
            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
        }
        if (n) continue;

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<ll> primeFactors(ll N) {
    vector<ll> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<ll> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e7);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

        ll c = a * b;
        vector<mp> fc = getFactors(c);
        ll no = 0;
        for (ull i = 0; i < fc.size(); i++) {
            if (fc[i].Y % 3 != 0) { no = 1; break; }
        }
        if (no) { cout << "No" << "\n"; continue; }

        ///////////////////////////////////////

        //if (a < b) { ll t = a; a = b; b = t; }

//        ll no = 0;
//        ll PF_idx = 0, PF = primes[PF_idx];
//        while (PF * PF <= a) {
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

//            PF = primes[++PF_idx];
//        }
//        if (!no && a != 1) {
//            PF = a;
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; }
//            if (cntb > 0 && cnta == 0) { no = 1; }
//            if ((cnta + cntb) % 3 != 0) {no = 1; }
//        }

//        if (!no && b != 1) {
//            PF = b;
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; }
//            if (cntb > 0 && cnta == 0) { no = 1; }
//            if ((cnta + cntb) % 3 != 0) {no = 1; }
//        }

//        if (no) { cout << "No" << "\n"; continue; }
            /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);
//        vector<mp> fb = primeFactors2(b);

//        //pr_vars(fa);
//        //pr_vars(fb);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;
         /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);

//        ll no = 0;
//        for (ull i = 0; i < fa.size(); i++) {
//            ll PF = fa[i].X;
//            ll cnta = fa[i].Y;
//            ll cntb = 0;
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }
//        }

//        if (b != 1) { no = 1; }

//        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<ll, ll>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<ll> primeFactors(ll N) {
    vector<ll> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<ll> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

//        ll c = a * b;
//        vector<mp> fc = getFactors(c);
//        ll no = 0;
//        for (ull i = 0; i < fc.size(); i++) {
//            if (fc[i].Y % 3 != 0) { no = 1; break; }
//        }
//        if (no) { cout << "No" << "\n"; continue; }

        ///////////////////////////////////////

        if (a < b) { ll t = a; a = b; b = t; }

        ll no = 0;
        ll PF_idx = 0, PF = primes[PF_idx];
        while (PF * PF <= a) {
            ll cnta = 0, cntb = 0;
            while (a % PF == 0) { a /= PF; cnta++; }
            while (b % PF == 0) { b /= PF; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; break; }
            if (cntb > 0 && cnta == 0) { no = 1; break; }

            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

            PF = primes[++PF_idx];
        }
        if (!no && a != 1) {
            ll cnta = 1, cntb = 0;
            while (b % a == 0) { b /= a; cntb++; }

            if (cnta > 0 && cntb == 0) { no = 1; }
            if (cntb > 0 && cnta == 0) { no = 1; }
            if ((cnta + cntb) % 3 != 0) {no = 1; }
        }

        if (!no && b != 1) { no = 1; }

        if (no) { cout << "No" << "\n"; continue; }
            /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);
//        vector<mp> fb = primeFactors2(b);

//        //pr_vars(fa);
//        //pr_vars(fb);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;
         /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);

//        ll no = 0;
//        for (ull i = 0; i < fa.size(); i++) {
//            ll PF = fa[i].X;
//            ll cnta = fa[i].Y;
//            ll cntb = 0;
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }
//        }

//        if (b != 1) { no = 1; }

//        if (no) { cout << "No" << "\n"; continue; }

        cout << "Yes" << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#ifndef ONLINE_JUDGE
  #define pr_debug(...) do { printf("DEBUG: line %d: %s: ", __LINE__, __PRETTY_FUNCTION__); printf(__VA_ARGS__); } while(0)
  #define pr_vars(...) do { pr_debug(" "); pr_var(split(#__VA_ARGS__, ',').begin(), __VA_ARGS__); } while(0)
#else
  __attribute__ ((constructor)) static void fast_cin() { ios_base::sync_with_stdio(false); cin.tie(0); }
  #define pr_debug(...) do { } while(0)
  #define pr_vars(...) do { } while(0)
#endif /* ONLINE_JUDGE */

using ll = int64_t;
using ull = uint64_t;
#define X first
#define Y second

using mp = pair<int, int>;

ostream &operator<< (ostream &fout, const vector<mp> &vec)
{ for (const auto &el : vec) fout << el.X << "=" << el.Y << ' '; return fout; }

template<typename T> ostream &operator<< (ostream &fout, const vector<T> &vec)
{ for (const auto &el : vec) fout << el << ' '; return fout; }

template<typename T> istream &operator>> (istream &fin, vector<T> &vec)
{ for (size_t i = 0; i < vec.size(); i++) fin >> vec[i]; return fin; }

vector<string> split(const string &s, char c) { vector<string> v; ull st = 0, fn = 0, lvl = 0;
for ( ; fn < s.size(); fn++ ) { if (s[fn] == c && lvl == 0) { v.push_back(s.substr(st, fn - st)); st = fn + 1; }
if (s[fn] == '(') { lvl++; } if (s[fn] == ')') { lvl--; } } v.push_back(s.substr(st, fn - st)); return v; }

void pr_var(vector<string>::iterator it) { (void) it; cout << endl; }
template<typename T, typename... Args> void pr_var(vector<string>::iterator it, T a, Args... args)
{ cout << *it << "=" << a << "  "; pr_var(++it, args...); }

ll div_ceil(ll n, ll d) { ll res = n / d; if (res >= 0) res += n % d ? 1 : 0; return res; }
ll gcd(ll a, ll b) { a = llabs(a); b = llabs(b); while (a && b) a > b ? a %= b : b %= a; return a + b; }
ll lcm(ll a, ll b) { ll c = gcd(a, b); return c == 0 ? 0 : llabs(a / c * b); }

#define setp(a) fixed << setprecision(a)
const double PI = acos(-1.0);
constexpr double EPS = 1e-9;
constexpr double INF = 2e18;

using mt = tuple<ll, ll, ll>;    // unpack: tie(ll, ll, ll) = mt;

constexpr ll MAX = 1e5 + 5;

// the last found prime will be 9999991
constexpr ll sieve_max_size = 1e7 + 10;
static bitset<sieve_max_size> bs;
static ll sieve_size;
static vector<int> primes;

// creates list of primes in [0..upperbound]
void sieve(ll upperbound) {
    sieve_size = upperbound + 1;
    bs.set();
    bs[0] = bs[1] = 0;
    for (ll i = 2; i <= sieve_size; i++) {
        if (bs[i] == 0) continue;
        for (ll j = i * i; j <= sieve_size; j += i)
            bs[j] = 0;
        primes.push_back((int)i);
    }
}

// deterministic prime tester for N <= sieve_size ** 2
bool isPrime(ll N) {
    if (N <= sieve_size) return bs[N];
    for (ull i = 0; i < primes.size(); i++)
        if (N % primes[i] == 0) return false;
    return true;
}

// finds Prime Factors with Optimized Trial Divisions
// good for up to 9999991 ** 2 == 99999820000081 ~= 9e13
vector<int> primeFactors(ll N) {
    vector<int> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        while (N % PF == 0) { N /= PF; factors.push_back(PF); }
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(N); }
    return factors;
}

vector<mp> getFactors(ll N) {
    vector<int> pr = primeFactors(N);
    vector<mp> factors; // prime-power factorization

    ll f = pr[0], c = 1;
    for (ull i = 1; i < pr.size(); i++) {
        if (pr[i] == f) c++;
        else { factors.push_back(mp(f, c)); f = pr[i]; c = 1; }
    }
    factors.push_back(mp(f, c));

    return factors;
}

vector<mp> primeFactors2(ll N) {
    vector<mp> factors;
    ll PF_idx = 0, PF = primes[PF_idx];
    while (PF * PF <= N) {
        ll cnt = 0;
        while (N % PF == 0) { N /= PF; cnt++; }
        if (cnt) factors.push_back(mp(PF, cnt));
        PF = primes[++PF_idx];
    }
    if (N != 1) { factors.push_back(mp(N, 1)); }
    return factors;
}

int main()
{
    sieve(1e6);

    ll n; cin >> n;
    for (ll tc = 0; tc < n; tc++) {
        ll a, b; cin >> a >> b;

        pr_vars(a, b);

        if (a == 1 && b == 1) { cout << "Yes" << "\n"; continue; }
        if (a == 1 && b != 1) { cout << "No" << "\n"; continue; }
        if (b == 1 && a != 1) { cout << "No" << "\n"; continue; }

        ll c = a * b;
        vector<mp> fc = getFactors(c);
        ll no = 0;
        for (ull i = 0; i < fc.size(); i++) {
            if (fc[i].Y % 3 != 0) { no = 1; break; }
        }
        if (no) { cout << "No" << "\n"; continue; }

        ///////////////////////////////////////

//        if (a < b) { ll t = a; a = b; b = t; }

//        ll no = 0;
//        ll PF_idx = 0, PF = primes[PF_idx];
//        while (PF * PF <= a) {
//        //while (PF <= a) {
//            ll cnta = 0, cntb = 0;
//            while (a % PF == 0) { a /= PF; cnta++; }
//            while (b % PF == 0) { b /= PF; cntb++; }

//            if (cnta > 0 && cntb == 0) { no = 1; break; }
//            if (cntb > 0 && cnta == 0) { no = 1; break; }

//            if ((cnta + cntb) % 3 != 0) {no = 1; break; }

//            PF = primes[++PF_idx];
//        }
//        if (a != 1 && b != 1) { no = 1; }

//        if (no) { cout << "No" << "\n"; continue; }
            /////////////////////////////////////////////

//        vector<mp> fa = primeFactors2(a);
//        vector<mp> fb = primeFactors2(b);

//        //vector<mp> fa = getFactors(a);
//        //vector<mp> fb = getFactors(b);

//        pr_vars(fa);
//        pr_vars(fb);

//        ll n = 0;
//        if (fa.size() != fb.size()) { cout << "No" << "\n"; continue; }
//        for (ull i = 0; i < fa.size(); i++) {
//            if (fa[i].X != fb[i].X) { n = 1; cout << "No" << "\n"; break; }
//            ll cnt = fa[i].Y + fb[i].Y;
//            if (cnt % 3 != 0) { n = 1; cout << "No" << "\n"; break; }
//        }
//        if (n) continue;

        cout << "Yes" << "\n";
    }
    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<ll ,ll> lo;
vector< pair <ll,ll> > v;

int main()
{
 ll n;
 cin>>n;
 while(n--)
 {
     ll c,v;
     cin>>c>>v;
     ll p=cbrt(c*v+min(c,v));
     if(c%p==0&&v%p==0)
     {
         cout<<"Yes\n";
     }
     else
     {
         cout<<"No\n";
     }
 }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll t=cbrt(k*h+1);
        ll p=__gcd(k,h);
        k=k/p;
        h/=p;
        ll u=cbrt(k*h+1);
        //cout<<u<<" ";
        if(h*k==p||(u*u*u==k*h&&p!=1&&t*t*t==k*h*p*p))
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<ll ,ll> lo;
vector< pair <ll,ll> > v;

int main()
{
 ll n;
 cin>>n;
 while(n--)
 {
     ll c,v;
     cin>>c>>v;
     ll p=ceil(cbrt(c*v));
     if(c%p==0&&v%p==0&&p*p*p==c*v)
     {
         cout<<"Yes\n";
     }
     else
     {
         cout<<"No\n";
     }
 }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

double diff(double n,double mid)
{
	if (n > (mid*mid*mid))
		return (n-(mid*mid*mid));
	else
		return ((mid*mid*mid) - n);
}

// Returns cube root of a no n
double cubicRoot(double n)
{
	// Set start and end for binary search
	double start = 0, end = n;

	// Set precision
	double e = 0.0000001;

	while (true)
	{
		double mid = (start + end)/2;
		double error = diff(n, mid);

		// If error is less than e then mid is
		// our answer so return mid
		if (error <= e)
			return mid;

		// If mid*mid*mid is greater than n set
		// end = mid
		if ((mid*mid*mid) > n)
			end = mid;

		// If mid*mid*mid is less than n set
		// start = mid
		else
			start = mid;
	}
}

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll u=cubicRoot(k*h);
        ll p=__gcd(k,h);
        k=k/p;
        h/=p;

        if(h*k==p||u*u*u==k*h*p*p)
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<ll ,ll> lo;
vector< pair <ll,ll> > v;

int main()
{
 ll n;
 cin>>n;
 long double a,b;
 while(n--)
 {
    cin>>a>>b;

     ll p=ceil(cbrt(a*b));
     if(p*p*p!=(a*b))
     {
          cout<<"No\n";
          continue;
     }
     if(fmod(a,p)==0&&fmod(b,p)==0)
     {
         cout<<"Yes\n";
     }
     else
     {
         cout<<"No\n";
     }
 }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<ll ,ll> lo;
vector< pair <ll,ll> > v;

int main()
{
 ll n;
 scanf("%lld",&n);
 long double a,b;
 while(n--)
 {
    scanf("%Lf %Lf",&a,&b);

     ll p=ceil(cbrt(a*b));
     if(p*p*p!=(a*b))
     {
          cout<<"No\n";
          continue;
     }
     if(fmod(a,p)==0&&fmod(b,p)==0)
     {
         cout<<"Yes\n";
     }
     else
     {
         cout<<"No\n";
     }
 }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<ll ,ll> lo;
vector< pair <ll,ll> > v;

int main()
{
 ll n;
 cin>>n;
 while(n--)
 {
     ll c,v;
     cin>>c>>v;
     ll p=cbrt(c*v+1);
     if(c%p==0&&v%p==0)
     {
         cout<<"Yes\n";
     }
     else
     {
         cout<<"No\n";
     }
 }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll t=cbrt(k*h+1);
        ll p=__gcd(k,h);
        if(p==1)
        {
            cout<<"No\n";
            continue;
        }
        if(h==k)
        {
            if(t*t*t==k*h)
            {
                cout<<"Yes\n";

            }
            else
            {
                cout<<"No\n";
            }
            continue;
        }
        k=k/p;
        h/=p;
        ll u=cbrt(k*h+1);
        //cout<<u<<" ";
        if(h*k==p||(u*u*u==k*h&&p!=1))
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        if(k==1&&h==1)
        {
            cout<<"Yes\n";
            continue;
        }

        ll u=cbrt(k*h+1);
        ll p=__gcd(k,h);
        if(p==1)
        {
            cout<<"No\n";
            continue;
        }
        k=k/p;
        h/=p;
        //cout<<u<<" ";
        if(h*k==p||(u*u*u==k*h*p*p&&p!=1))
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll u=cbrt(k*h);
        ll p=__gcd(k,h);
        k=k/p;
        h/=p;

        if(h*k==p||u*u*u==k*h*p*p)
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll u=cbrt(k*h+1);
        ll p=__gcd(k,h);
        k=k/p;
        h/=p;
        //cout<<u<<" ";
        if(h*k==p||(u*u*u==k*h*p*p&&p!=1))
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long int
#define pb emplace_back
#define mp make_pair
#define MOD 1000000007
#define For(i,n) for(ll i=0;i<n;i++)
using namespace std;
unordered_map<int, bool>lo;

double diff(double n,double mid)
{
	if (n > (mid*mid*mid))
		return (n-(mid*mid*mid));
	else
		return ((mid*mid*mid) - n);
}

// Returns cube root of a no n
double cubicRoot(double n)
{
	// Set start and end for binary search
	double start = 0, end = n;

	// Set precision
	double e = 0.0000001;

	while (true)
	{
		double mid = (start + end)/2;
		double error = diff(n, mid);

		// If error is less than e then mid is
		// our answer so return mid
		if (error <= e)
			return mid;

		// If mid*mid*mid is greater than n set
		// end = mid
		if ((mid*mid*mid) > n)
			end = mid;

		// If mid*mid*mid is less than n set
		// start = mid
		else
			start = mid;
	}
}

int main()
{
    ll n;
    cin>>n;
    while(n--)
    {
        ll k,h;
        cin>>k>>h;
        ll p=__gcd(k,h);
        k=k/p;
        h/=p;
        ll u=cubicRoot(k*h);
        if(h*k==p||u*u*u==k*h)
        {
            cout<<"Yes\n";
        }
        else
        {
            cout<<"No\n";
        }
    }

    return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

vector<ll> factor;

void prime_factor(ll n) {
	for (ll i = 2; i * i <= n; ++i) {
		while (n % i == 0) {
			n = n / i;
			factor.push_back(i);
		}
	}
	if (n > 1) {
		factor.push_back(n);
	}

}
int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;

	map<ll, int> ma;
	map<ll, int> mb;

	cin >> n;
	while (n--) {

		cin >> a >> b;
		ma.clear();
		mb.clear();
		factor.clear();

		prime_factor(a);
		for (int i = 0; i < SZ(factor); ++i) {
			ma[factor[i]]++;
		}
		factor.clear();
		prime_factor(b);
		for (int i = 0; i < SZ(factor); ++i) {
			mb[factor[i]]++;
		}

		if (SZ(ma) != SZ(mb)) {
			cout << "NO" << endl;
			continue;
		}
		auto it1 = ma.begin();
		auto it2 = mb.begin();
		bool b = 0;
		for (int i = 0; i < SZ(ma); ++i) {
			int x1 = it1->first;
			int x2 = it2->first;
			int y1 = it1->second;
			int y2 = it2->second;
//			cout << x1 << " " << y1 << endl;
//			cout << x2 << " " << y2 << endl;

			if (x1 != x2) {
				cout << "NO" << endl;
				b = 1;
			}
			int z = y1 + y2;
			if (z % 3 != 0) {
				cout << "NO" << endl;
				b = 1;
			}
			z = z / 3;

			if (min(y1, y2) >= z && max(y1, y2) <= 2 * z) {

			} else {
				cout << "NO" << endl;
				b = 1;
			}
			it1++;
			it2++;
		}
		if (b)
			cout << "NO" << endl;
		else
			cout << "YES" << endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n;
	ll a, b;
	scanf("%d", &n);

	while (n--) {
		scanf("%lld %lld", &a, &b);
		ll mul = cbrt(a * b) + 0.5;

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n;
	ll a, b;
	scanf("%d", &n);

	while (n--) {

		scanf("%I64d %I64d", &a, &b);
		ll mul = (cbrt(a * b) + 0.5);

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	cin.tie(0);
	cin.sync_with_stdio(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b) + 0.5;

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

vector<ll> factor;

void prime_factor(ll n) {
	for (ll i = 2; i * i <= n; ++i) {
		while (n % i == 0) {
			n = n / i;
			factor.push_back(i);
		}
	}
	if (n > 1) {
		factor.push_back(n);
	}

}
int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;

	map<ll, int> ma;
	map<ll, int> mb;

	cin >> n;
	while (n--) {

		cin >> a >> b;
		ma.clear();
		mb.clear();
		factor.clear();

		prime_factor(a);
		for (int i = 0; i < SZ(factor); ++i) {
			ma[factor[i]]++;
		}
		factor.clear();
		prime_factor(b);
		for (int i = 0; i < SZ(factor); ++i) {
			mb[factor[i]]++;
		}

		if (SZ(ma) != SZ(mb)) {
			cout << "No" << endl;
			continue;
		}
		auto it1 = ma.begin();
		auto it2 = mb.begin();
		bool b = 0;
		for (int i = 0; i < SZ(ma); ++i) {
			int x1 = it1->first;
			int x2 = it2->first;
			int y1 = it1->second;
			int y2 = it2->second;
//			cout << x1 << " " << y1 << endl;
//			cout << x2 << " " << y2 << endl;

			if (x1 != x2) {
				b = 1;

				break;
			}
			int z = y1 + y2;
			if (z % 3 != 0) {
				b = 1;

				break;
			}
			z = z / 3;

			if (min(y1, y2) >= z && max(y1, y2) <= 2 * z) {

			} else {
				b = 1;

				break;
			}
			it1++;
			it2++;
		}
		if (b)
			cout << "No" << endl;
		else
			cout << "Yes" << endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b) + 0.00001;

		if (mul * mul * mul == a * b && a % mul == 0 && b % mul == 0) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {

	int n;
	long long a, b;
	scanf("%d", &n);

	while (n--) {

		scanf("%I64d %I64d", &a, &b);
		long long mul = (cbrt(a * b) + 0.5);

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			printf("Yes\n");
		} else {
			printf("No\n");
		}
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {

	int n;
	long long a, b;
	scanf("%d", &n);

	while (n--) {

		scanf("%I64d %I64d", &a, &b);
		long long mul = (cbrt(a * b));

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			printf("Yes\n");
		} else {
			printf("No\n");
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b);
		if (mul * mul == a / mul * b && a % mul == 0 && b % mul == 0) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {

	int n;
	ll a, b;
	scanf("%d", &n);

	while (n--) {

		scanf("%I64d %I64d", &a, &b);
		ll mul = (cbrt(a * b) + 0.5);

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {

	int n;
	long long a, b;
	scanf("%d", &n);

	while (n--) {

		scanf("%I64d %I64d", &a, &b);
		long long mul = (cbrt(a * b) + 0.5);

		if ((mul * mul * mul == a * b) && (a % mul == 0) && (b % mul == 0)) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b);
		if (mul * mul * mul == a * b && a % mul == 0 && b % mul == 0) {
			cout << "Yes" << endl;
		}else{
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

bool PF(ll a, ll b) {

	int c1, c2;
	for (ll i = 2; i * i <= a || i * i <= b; ++i) {
		c1 = 0;
		c2 = 0;
		while (a % i == 0) {
			c1++;
			a = a / i;
		}
		while (b % i == 0) {
			c2++;
			b = b / i;
		}
		int z = c1 + c2;
		if (z == 0) {
			continue;
		}
		if (z % 3 != 0)
			return 0;

		if (c1 > c2) {
			swap(c1, c2);
		}
		z = z / 3;
//		cout << c1 << " " << c2 << endl;
		if (c1 < z || c2 > 2 * z) {
			return 0;
		}
	}

	return 1;
}
int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	ll a, b;
	int n;
	cin >> n;

	while (n--) {
		cin >> a >> b;
		if (PF(a, b)) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	std::ios::sync_with_stdio(0);
	cin.tie(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b) + 0.00001;

		if (mul * mul * mul == a * b && a % mul == 0 && b % mul == 0) {
			cout<<"Yes"<<endl;
		} else {
			cout<<"No"<<endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	std::cin.tie(0);
	std::ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n;
	ll a, b;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		ll mul = cbrt(a * b) + 0.00001;

		if (mul * mul * mul == a * b && a % mul == 0 && b % mul == 0) {
			cout << "Yes" << endl;
		} else {
			cout << "No" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

#define SZ(s) (int)s.size()
#define ALL(v) v.begin(), v.end()
#define clr(a,v) memset(a,v,sizeof a)

typedef long long ll;
typedef unsigned long long ull;

vector<ll> factor;

void prime_factor(ll n) {
	for (ll i = 2; i * i <= n; ++i) {
		while (n % i == 0) {
			n = n / i;
			factor.push_back(i);
		}
	}
	if (n > 1) {
		factor.push_back(n);
	}

}
int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);

	int n;
	ll a, b;

	unordered_map<ll, int> ma;
	unordered_map<ll, int> mb;

	cin >> n;
	while (n--) {

		cin >> a >> b;
		ma.clear();
		mb.clear();
		factor.clear();

		prime_factor(a);
		for (int i = 0; i < SZ(factor); ++i) {
			ma[factor[i]]++;
		}
		factor.clear();
		prime_factor(b);
		for (int i = 0; i < SZ(factor); ++i) {
			mb[factor[i]]++;
		}

		if (SZ(ma) != SZ(mb)) {
			cout << "No" << endl;
			continue;
		}
		auto it1 = ma.begin();
		auto it2 = mb.begin();
		bool b = 0;
		for (int i = 0; i < SZ(ma); ++i) {
			int x1 = it1->first;
			int x2 = it2->first;
			int y1 = it1->second;
			int y2 = it2->second;
//			cout << x1 << " " << y1 << endl;
//			cout << x2 << " " << y2 << endl;

			if (x1 != x2) {
				b = 1;

				break;
			}
			int z = y1 + y2;
			if (z % 3 != 0) {
				b = 1;

				break;
			}
			z = z / 3;

			if (min(y1, y2) >= z && max(y1, y2) <= 2 * z) {

			} else {
				b = 1;

				break;
			}
			it1++;
			it2++;
		}
		if (b)
			cout << "No" << endl;
		else
			cout << "Yes" << endl;
	}
	return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 32000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            if (!ok) break;
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
#include<cstdio>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

int main()
{
    initqbs();

  //  doprime();
   // cout << primes_c << endl;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            printf("Yes\n");
            continue;
        }
        if ((a == b*b) || (b == a*a))
        {
            printf("Yes\n");
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            printf("No\n");
            continue;
        }
        int j = 0;
        bool ok = true;
        a /= sq;
        b /= sq;
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            printf("Yes\n");
            continue;
        }
        else
        {
            printf("No\n");
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            if (!ok) break;
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
    cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            if (!ok) break;
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

int main()
{
    initqbs();

    doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if ((a == b*b) || (b == a*a))
        {
            cout << "Yes" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            if (!ok) break;
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }

        vector<int> f,s,tt(200000);
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                tt[primes[j]]++;
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
#include<cstdio>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

int main()
{
    initqbs();

  //  doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            printf("Yes\n");
            continue;
        }
        if ((a == b*b) || (b == a*a))
        {
            printf("Yes\n");
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            printf("No\n");
            continue;
        }
        int j = 0;
        bool ok = true;
        a /= sq;
        b /= sq;
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            printf("Yes\n");
            continue;
        }
        else
        {
            printf("No\n");
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        while(sq > 1 && j<primes_c)
        {
            if (!ok) break;
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 32000; i+=2)
    {
        bool ok = true;
        for(int j = 0; j < primes_c; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

int main()
{
    initqbs();

    doprime();
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        vector<int> f,s,tt(32000);
        int j = 0;
        bool ok = true;
        while(sq > 1)
        {
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                tt[primes[j]]++;
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

int main()
{
    initqbs();

  //  doprime();
   // cout << primes_c << endl;
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if ((a == b*b) || (b == a*a))
        {
            cout << "Yes" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }
        int j = 0;
        bool ok = true;
        a /= sq;
        b /= sq;
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}


#include <iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;

vector<int> primes;
int primes_c;

void doprime()
{
    primes.push_back(2);
    primes.push_back(3);
    primes.push_back(5);
    primes_c = 3;
    for(int i = 7; i <= 1000000; i+=2)
    {
        bool ok = true;
        int s = sqrt(i);
        for(int j = 0; j < primes_c && primes[j] <= s; j++)
        {
            if (i % primes[j] == 0)
            {
                ok = false;
                break;
            }
        }
        if (ok)
        {
            primes_c++;
            primes.push_back(i);
        }
    }
}

vector<unsigned long long> qbs(1000000);

void initqbs()
{
    for(int i = 1; i <= 1000000; i++)
    {
        qbs[i] = i;
        qbs[i] *= i;
        qbs[i] *= i;
    }
}

bool isprime(int a)
{
    if (a == 2) return true;
    if (a % 2 == 0) return false;
    int s = sqrt(a)+10;
    for(int i = 3; i <= s; i+=2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    initqbs();

    doprime();
    int n;
    cin >> n;
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        int c = a,d = b;
        if ((a == b) && (b == 1))
        {
            cout << "Yes" << endl;
            continue;
        }
        if (isprime(a))
        {
            if (b == a*a)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        if (isprime(b))
        {
            if (a == b*b)
            {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
            continue;
        }
        unsigned long long res = a;
        res *= b;
        int sq = lower_bound(qbs.begin(), qbs.end(),res) - qbs.begin();
        unsigned long long w = sq;
        w*=sq;
        w*=sq;
        if (w != res)
        {
            cout << "No" << endl;
            continue;
        }

        vector<int> f,s,tt(32000);
        int j = 0;
        bool ok = true;
        while(sq > 1)
        {
            while(sq % primes[j] == 0)
            {
                sq /= primes[j];
                tt[primes[j]]++;
                if ((a%primes[j] == 0) && (b%primes[j] == 0))
                {
                    a /= primes[j];
                    b /= primes[j];
                }
                else
                {
                    cout << "No" << endl;
                    ok = false;
                    break;
                }
            }
            j++;
        }
        if (!ok) continue;
        int a1 = a, b1 = b;
        if ((a1*a1*b1 == c) && (a1*b1*b1 == d))
        {
            cout << "Yes" << endl;
            continue;
        }
        else
        {
            cout << "No" << endl;
            continue;
        }
    }
    return 0;
}