思路:

cpp
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define fi first
#define se second
#define lson p << 1
#define rson p << 1 | 1
const int maxn = 1e6 + 5, inf = 1e18 * 3, maxm = 4e4 + 5, mod = 1e9 + 7;
int a[maxn], b[maxn];
int n, m;
string s;
bool vis[maxn];
vector<int> G[maxn];
int from, to;
vector<int> tmp, vec;
int deg[maxn];
void dfs(int u, int p){
if(u == to && p == from) return;
if(vis[u]) return;
vis[u] = 1;
tmp.pb(u);
if(u == to){
vec = tmp;
return;
}
for(auto v : G[u]){
dfs(v, u);
}
tmp.pop_back();
}
void solve(){
int res = 0;
int k, x, q;
cin >> n >> m;
for(int i = 1; i <= n; i++){
G[i].clear();
deg[i] = 0;
}
for(int i = 1; i <= m; i++){
int u, v;
cin >> u >> v;
G[u].pb(v);
G[v].pb(u);
deg[u]++;
deg[v]++;
}
for(int u = 1; u <= n; u++){
if(deg[u] < 4) continue;
for(auto v : G[u]){
for(int i = 1; i <= n; i++){
vis[i] = 0;
}
from = u;
to = v;
vec.clear();
tmp.clear();
dfs(u, u);
if(vec.empty()) continue;
vector<int> extra;
tmp.clear();
for(auto x : G[u]){
if(x == vec.back() || x == *(vec.begin() + 1)) continue;
if(find(vec.begin(), vec.end(), x) == vec.end()){//不在环内
extra.pb(x);
if(extra.size() == 2) break;
}
else{
tmp.pb(x);//在环内,且与u相连
}
}
vector<int> vt;
if(extra.size() < 2){
for(auto x : vec){
vt.pb(x);
if(find(tmp.begin(), tmp.end(), x) != tmp.end()){//在tmp内
break;
}
}
extra.pb(vec.back());
for(int i = vec.size() - 1; i >= 0; i--){
int x = vec[i];
if(find(tmp.begin(), tmp.end(), x) != tmp.end()){
extra.pb(x);
break;
}
}
// extra.pb(vec.end() - 2) 不能这样写,因为这个结点不一定与u相连
// extra.pb(tmp.back()); 不能这样写,因为tmp的顺序跟环的结点顺序不一致
extra.resize(2);
vec = vt;
}
cout << "Yes\n";
cout << vec.size() + 2 << '\n';
int m = vec.size();
for(int i = 0; i < vec.size(); i++){
cout << vec[i] << ' ' << vec[(i + 1) % m] << '\n';
}
cout << u << ' ' << extra[0] << '\n';
cout << u << ' ' << extra[1] << '\n';
return;
}
}
cout << "No\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}