#pragma GCC optimize("Ofast")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
#define pb push_back
#define eb emplace_back
#define rep(i,a,b) for(int i=(int)(a); i < (int)(b);i++)
#define all(x) (x).begin(), (x).end()
#define debug(x) cout << #x << ": " << x << endl
#define esp ' '
#define pii pair<int,int>
#define vi vector<int>
#define sz(x) ((int)(x).size())
using namespace std;
constexpr int oo = 0x3f3f3f3f3f3f3f3f;
constexpr int M = 23785125;
constexpr int mxI = 36;
constexpr ll MOD1 = 21412641264812894;
constexpr ll MOD2 = 17841234164112412;
struct DSU {
vi p, rnk;
DSU(int n) : p(n), rnk(n,0) {
iota(all(p),0);
}
int find(int x) {
return p[x] == x ? x : p[x]=find(p[x]);
}
bool merge(int a, int b) {
a=find(a);
b=find(b);
if (a == b) return false;
if (rnk[a] > rnk[b]) swap(a,b);
rnk[b] += rnk[a]==rnk[b];
p[a]=b;
return true;
}
};
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n,m;cin>>n>>m;
vector<pair<int,int>> edges(m);
rep(i,0,m) {
int a,b;cin>>a>>b;a--;b--;
edges[i]={a,b};
}
if (m == n-1) {
cout << "YES\n";
return;
}
auto hash=[&](auto self, vector<vi>& g, int a, int p=-1) -> ll{
vector<ll> sons;
for (auto b : g[a]) if (b != p) {
sons.pb(self(self, g, b, a));
}
sort(all(sons));
ll po=418417123;
ll ans=1958473849193;
for (auto x : sons) {
ans += po * x;
if (ans >= 412412355) ans -= 36162378;
//ans %= MOD1;
po *= M;
//po %= MOD1;
}
return ans;
};
auto test=[&](vector<vi>& g) {
vi szs(n,0), ps(n);
auto dfs1=[&](auto self, int a, int p) -> void{
ps[a] = p;
szs[a] = 1;
for (auto b : g[a]) if (b != p) {
self(self, b, a);
szs[a] += szs[b];
}
};
dfs1(dfs1, 0,-1);
auto ctrd=[&](int a) {
if (2*(n - szs[a]) > n) return false;
for (auto b : g[a]) if (b != ps[a]) {
if (2*szs[b] > n) return false;
}
return true;
};
vi ctrds;
rep(a,0,n) {
if (ctrd(a)) ctrds.pb(a);
}
vector<ll> ans;
for (auto x : ctrds) ans.eb(hash(hash, g, x));
return ans;
};
auto is_eq = [&](vector<ll> a, vector<ll> b) {
if (sz(a) != sz(b)) return false;
sort(all(a));
sort(all(b));
return a == b;
};
DSU dsu(n);
auto dfstree=[&](vector<vi>& tree) {
iota(all(dsu.p), 0);
memset(&dsu.rnk[0], 0, n*sizeof(int));
tree.assign(n, vi());
shuffle(all(edges), rng);
for (auto [a,b] : edges) {
if (!dsu.merge(a,b)) continue;
tree[a].pb(b);
tree[b].pb(a);
}
};
vector<vi> tree(n);
dfstree(tree);
auto hashs = test(tree);
rep(_, 1, mxI) {
dfstree(tree);
auto hashc = test(tree);
if (!is_eq(hashc, hashs)) {
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
signed main() {
ios_base::sync_with_stdio(0);cin.tie(0);
int t=1;
cin>>t;
while(t--) solve();
}