#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define zeros(x) x^(x-1)&x
#define pii pair<ll,ll>
#define Nmax 2500
using namespace std;

const int INF = 2e9;

int n, m, fst, a, b;
bool uz[Nmax];
vector<int> v[Nmax];
vector<pii> ans;

int cycle(int nod, int ant, int lg){
    if (uz[nod]) return 0;
    uz[nod] = 1;
    int ok = 0;
    for (auto it : v[nod]){
        if (it == ant && !ok){
            ok = 1;
            continue;
        }
        if (uz[it]){
            if (it != fst) return 1;
            else return lg;
        }
        int x = cycle(it, nod, lg+1);
        if (x) return x;
    }
    return 0;
}

bool conex(int a, int b){
    uz[a] = 1;
    if (a==b) return 1;
    for (auto it : v[a]){
        if (uz[it]) continue;
        return conex(it,b);
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i=1;i<=m;i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    int ok = -1;
    for (int i=1;i<=n;i++){
        if (v[i].size() > 2){
            cout << "NO\n";
            return 0;
        }
        fst = i;
        int x = cycle(i, -1, 1);
        if (x == n) ok = 1;
        else if (x) ok = 0;
    }
    if (ok == 0){
        cout << "NO\n";
        return 0;
    }

    vector<pii> e;
    for (int i=1;i<=n;i++)
        if (v[i].size()==1)
            e.push_back({i,1});

    int sav = 0;
    for (int i=1;i<=n;i++){
        if (v[i].size() == 0){
            e.push_back({i,0});
        }
    }
    sort(e.begin(),e.end());

    ok = 0;
    for (int i=0;i<e.size();i++){
        for (int j=i+1;j<e.size();j++){
            memset(uz,0,sizeof(uz));
            bool x = conex(e[i].first,e[j].first);
            if (e[i].second <= 1 && e[j].second <= 1 && !x){
                v[e[i].first].push_back(e[j].first);
                v[e[j].first].push_back(e[i].first);
                ans.push_back({min(e[i].first,e[j].first), max(e[i].first,e[j].first)});
                e[i].second++;
                e[j].second++;
                sort(e.begin(),e.end());
                i = 0;
                j = 0;
                continue;
            }
        }
    }

    int a = 0, b = 0, aux = 0;
    for (int i=0;i<e.size();i++){
        if (e[i].second == 0){
            if (!aux) aux = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
        else if (e[i].second == 1){
            if (!a) a = e[i].first;
            else if (!b) b = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
    }

    if (aux && n==1) ans.push_back({aux,aux});
    else if (aux){
        cout << "NO\n";
        return 0;
    }
    else if (!aux && a && b) ans.push_back({min(a,b), max(a,b)});
    else if (!aux && a){
        cout << "NO\n";
        return 0;
    }
    sort(ans.begin(),ans.end());

    cout << "YES\n";
    cout << ans.size() << '\n';
    for (auto it : ans){
        cout << it.first << ' ' << it.second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define zeros(x) x^(x-1)&x
#define pii pair<ll,ll>
#define Nmax 2500
using namespace std;

const int INF = 2e9;

int n, m, fst, a, b;
bool uz[Nmax];
vector<int> v[Nmax];
vector<pii> ans;

int cycle(int nod, int ant, int lg){
    if (uz[nod]) return 0;
    uz[nod] = 1;
    for (auto it : v[nod]){
        if (it == ant) continue;
        if (uz[it]){
            if (it != fst) return 1;
            else return lg;
        }
        int x = cycle(it, nod, lg+1);
        return x;
    }
    return 0;
}

bool conex(int a, int b){
    uz[a] = 1;
    if (a==b) return 1;
    for (auto it : v[a]){
        if (uz[it]) continue;
        return conex(it,b);
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i=1;i<=m;i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    int ok = -1;
    for (int i=1;i<=n;i++){
        if (v[i].size() > 2){
            cout << "NO\n";
            return 0;
        }
        fst = i;
        int x = cycle(i, -1, 1);
        if (x == n) ok = 1;
        else if (x) ok = 0;
    }
    if (ok == 0){
        cout << "NO\n";
        return 0;
    }

    vector<pii> e;
    for (int i=1;i<=n;i++)
        if (v[i].size()==1)
            e.push_back({i,1});

    int sav = 0;
    for (int i=1;i<=n;i++){
        if (v[i].size() == 0){
            e.push_back({i,0});
        }
    }
    sort(e.begin(),e.end());

    ok = 0;
    for (int i=0;i<e.size();i++){
        for (int j=i+1;j<e.size();j++){
            memset(uz,0,sizeof(uz));
            bool x = conex(e[i].first,e[j].first);
            if (e[i].second <= 1 && e[j].second <= 1 && !x){
                v[e[i].first].push_back(e[j].first);
                v[e[j].first].push_back(e[i].first);
                ans.push_back({min(e[i].first,e[j].first), max(e[i].first,e[j].first)});
                e[i].second++;
                e[j].second++;
                sort(e.begin(),e.end());
                i = 0;
                j = 0;
                continue;
            }
        }
    }

    int a = 0, b = 0;
    for (int i=0;i<e.size();i++){
        if (e[i].second == 0){
            cout << "NO\n";
            return 0;
        }
        else if (e[i].second == 1){
            if (!a) a = e[i].first;
            else if (!b) b = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
    }

    if (a && b) ans.push_back({min(a,b), max(a,b)});
    else if (a){
        cout << "NO\n";
        return 0;
    }
    sort(ans.begin(),ans.end());

    cout << "YES\n";
    cout << ans.size() << '\n';
    for (auto it : ans){
        cout << it.first << ' ' << it.second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define zeros(x) x^(x-1)&x
#define pii pair<ll,ll>
#define Nmax 2500
using namespace std;

const int INF = 2e9;

int n, m, fst, a, b;
bool uz[Nmax];
vector<int> v[Nmax];
vector<pii> ans;

int cycle(int nod, int ant, int lg){
    if (uz[nod]) return 0;
    uz[nod] = 1;
    for (auto it : v[nod]){
        if (it == ant) continue;
        if (uz[it]){
            if (it != fst) return 1;
            else return lg;
        }
        int x = cycle(it, nod, lg+1);
        return x;
    }
    return 0;
}

bool conex(int a, int b){
    uz[a] = 1;
    if (a==b) return 1;
    for (auto it : v[a]){
        if (uz[it]) continue;
        return conex(it,b);
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i=1;i<=m;i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    int ok = -1;
    for (int i=1;i<=n;i++){
        if (v[i].size() > 2){
            cout << "NO\n";
            return 0;
        }
        fst = i;
        int x = cycle(i, -1, 1);
        if (x == n) ok = 1;
        else if (x) ok = 0;
    }
    if (ok == 0){
        cout << "NO\n";
        return 0;
    }

    vector<pii> e;
    for (int i=1;i<=n;i++)
        if (v[i].size()==1)
            e.push_back({i,1});

    int sav = 0;
    for (int i=1;i<=n;i++){
        if (v[i].size() == 0){
            e.push_back({i,0});
        }
    }
    sort(e.begin(),e.end());

    ok = 0;
    for (int i=0;i<e.size();i++){
        for (int j=i+1;j<e.size();j++){
            memset(uz,0,sizeof(uz));
            bool x = conex(e[i].first,e[j].first);
            if (e[i].second <= 1 && e[j].second <= 1 && !x){
                v[e[i].first].push_back(e[j].first);
                v[e[j].first].push_back(e[i].first);
                ans.push_back({min(e[i].first,e[j].first), max(e[i].first,e[j].first)});
                e[i].second++;
                e[j].second++;
                sort(e.begin(),e.end());
                i = 0;
                j = 0;
                continue;
            }
        }
    }

    int a = 0, b = 0, aux = 0;
    for (int i=0;i<e.size();i++){
        if (e[i].second == 0){
            if (!aux) aux = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
        else if (e[i].second == 1){
            if (!a) a = e[i].first;
            else if (!b) b = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
    }

    if (aux && !a && !b) ans.push_back({aux,aux});
    else if (!aux && a && b) ans.push_back({min(a,b), max(a,b)});
    else if (!aux && a){
        cout << "NO\n";
        return 0;
    }
    sort(ans.begin(),ans.end());

    cout << "YES\n";
    cout << ans.size() << '\n';
    for (auto it : ans){
        cout << it.first << ' ' << it.second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define zeros(x) x^(x-1)&x
#define pii pair<ll,ll>
#define Nmax 2500
using namespace std;

const int INF = 2e9;

int n, m, fst, a, b;
bool uz[Nmax];
vector<int> v[Nmax];
vector<pii> ans;

int cycle(int nod, int ant, int lg){
    if (uz[nod]) return 0;
    uz[nod] = 1;
    for (auto it : v[nod]){
        if (it == ant) continue;
        if (uz[it]){
            if (it != fst) return 1;
            else return lg;
        }
        int x = cycle(it, nod, lg+1);
        if (x) return x;
    }
    return 0;
}

bool conex(int a, int b){
    uz[a] = 1;
    if (a==b) return 1;
    for (auto it : v[a]){
        if (uz[it]) continue;
        return conex(it,b);
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i=1;i<=m;i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    int ok = -1;
    for (int i=1;i<=n;i++){
        if (v[i].size() > 2){
            cout << "NO\n";
            return 0;
        }
        fst = i;
        int x = cycle(i, -1, 1);
        if (x == n) ok = 1;
        else if (x) ok = 0;
    }
    if (ok == 0){
        cout << "NO\n";
        return 0;
    }

    vector<pii> e;
    for (int i=1;i<=n;i++)
        if (v[i].size()==1)
            e.push_back({i,1});

    int sav = 0;
    for (int i=1;i<=n;i++){
        if (v[i].size() == 0){
            e.push_back({i,0});
        }
    }
    sort(e.begin(),e.end());

    ok = 0;
    for (int i=0;i<e.size();i++){
        for (int j=i+1;j<e.size();j++){
            memset(uz,0,sizeof(uz));
            bool x = conex(e[i].first,e[j].first);
            if (e[i].second <= 1 && e[j].second <= 1 && !x){
                v[e[i].first].push_back(e[j].first);
                v[e[j].first].push_back(e[i].first);
                ans.push_back({min(e[i].first,e[j].first), max(e[i].first,e[j].first)});
                e[i].second++;
                e[j].second++;
                sort(e.begin(),e.end());
                i = 0;
                j = 0;
                continue;
            }
        }
    }

    int a = 0, b = 0, aux = 0;
    for (int i=0;i<e.size();i++){
        if (e[i].second == 0){
            if (!aux) aux = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
        else if (e[i].second == 1){
            if (!a) a = e[i].first;
            else if (!b) b = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
    }

    if (aux && n==1) ans.push_back({aux,aux});
    else if (aux){
        cout << "NO\n";
        return 0;
    }
    else if (!aux && a && b) ans.push_back({min(a,b), max(a,b)});
    else if (!aux && a){
        cout << "NO\n";
        return 0;
    }
    sort(ans.begin(),ans.end());

    cout << "YES\n";
    cout << ans.size() << '\n';
    for (auto it : ans){
        cout << it.first << ' ' << it.second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define zeros(x) x^(x-1)&x
#define pii pair<ll,ll>
#define Nmax 2500
using namespace std;

const int INF = 2e9;

int n, m, fst, a, b;
bool uz[Nmax];
vector<int> v[Nmax];
vector<pii> ans;

int cycle(int nod, int ant, int lg){
    if (uz[nod]) return 0;
    uz[nod] = 1;
    for (auto it : v[nod]){
        if (it == ant) continue;
        if (uz[it]){
            if (it != fst) return 1;
            else return lg;
        }
        int x = cycle(it, nod, lg+1);
        return x;
    }
    return 0;
}

bool conex(int a, int b){
    uz[a] = 1;
    if (a==b) return 1;
    for (auto it : v[a]){
        if (uz[it]) continue;
        return conex(it,b);
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i=1;i<=m;i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    int ok = -1;
    for (int i=1;i<=n;i++){
        if (v[i].size() > 2){
            cout << "NO\n";
            return 0;
        }
        fst = i;
        int x = cycle(i, -1, 1);
        if (x == n) ok = 1;
        else if (x) ok = 0;
    }
    if (ok == 0){
        cout << "NO\n";
        return 0;
    }

    vector<pii> e;
    for (int i=1;i<=n;i++)
        if (v[i].size()==1)
            e.push_back({i,1});

    int sav = 0;
    for (int i=1;i<=n;i++){
        if (v[i].size() == 0){
            e.push_back({i,0});
        }
    }
    sort(e.begin(),e.end());

    ok = 0;
    for (int i=0;i<e.size();i++){
        for (int j=i+1;j<e.size();j++){
            memset(uz,0,sizeof(uz));
            bool x = conex(e[i].first,e[j].first);
            if (e[i].second <= 1 && e[j].second <= 1 && !x){
                v[e[i].first].push_back(e[j].first);
                v[e[j].first].push_back(e[i].first);
                ans.push_back({min(e[i].first,e[j].first), max(e[i].first,e[j].first)});
                e[i].second++;
                e[j].second++;
                sort(e.begin(),e.end());
                i = 0;
                j = 0;
                continue;
            }
        }
    }

    int a = 0, b = 0, aux = 0;
    for (int i=0;i<e.size();i++){
        if (e[i].second == 0){
            if (!aux) aux = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
        else if (e[i].second == 1){
            if (!a) a = e[i].first;
            else if (!b) b = e[i].first;
            else{
                cout << "NO\n";
                return 0;
            }
        }
    }

    if (aux && n==1) ans.push_back({aux,aux});
    else if (aux){
        cout << "NO\n";
        return 0;
    }
    else if (!aux && a && b) ans.push_back({min(a,b), max(a,b)});
    else if (!aux && a){
        cout << "NO\n";
        return 0;
    }
    sort(ans.begin(),ans.end());

    cout << "YES\n";
    cout << ans.size() << '\n';
    for (auto it : ans){
        cout << it.first << ' ' << it.second << '\n';
    }

    return 0;
}


/*
Author: Monem
*/
#include <bits/stdc++.h>

#define _CRT_SECURE_NO_WARNINGS
#define ll                long long int
#define ld                long double
#define neig(a, u, e, v) for(int v, e = a.head[u] ; ~e and (v = a.to[e], 1) ; e = a.nxt[e])
#define EPS            1e-9
#define all(v)            v.begin(),v.end()
#define X                first
#define Y                second
#define ii pair<int,int>

using namespace std;

ll MOD = 1e9 + 7;

const int N = 15, M = 1e5 + 10, NM1 = N - 1;
ll OO = 1e18 + 8;
int oo = 1e9 + 8;

void readFile() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen ("output.txt","w",stdout);
#endif
}

struct DSU {
    vector<int> par, sz;

    DSU(int n) { par.resize(n), sz.resize(n), iota(all(par), 0), fill(all(sz), 1); }

    int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }

    bool join(int u, int v) {
        int p1 = leader(u), p2 = leader(v);
        if (p1 == p2)return false;
        if (sz[p1] < sz[p2])swap(p1, p2);//p2 is bigger
        par[p2] = p1;
        sz[p1] += sz[p2];
        return true;
    }
} dsu(1);
int n, m, u, v, deg[55];
int main() {
    readFile();
    scanf("%d%d", &n, &m);
    dsu = DSU(n);
    bool ok = 1;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &u, &v);
        deg[--u]++, deg[--v]++;
        if(deg[u] > 2 || deg[v] > 2 || (u == v && n != 1)) ok = 0;
        if(!dsu.join(u, v) && i != n - 1 && i != m - 1) ok = 0;
    }
    if(!ok || n < m) return puts("NO"), 0;
    int cnt = n - m;
    printf("YES\n%d\n", cnt);
    for(int i = 0; i < n && cnt; i++){
        for(int j = i + 1; j < n && cnt && deg[i] < 2; j++){
            while(deg[j] < 2 && cnt && deg[i] < 2){
                printf("%d %d\n", i + 1, j + 1);
                deg[i]++, deg[j]++;
                cnt--;
            }
        }
    }
    return 0;
}


/*
Author: Monem
*/
#include <bits/stdc++.h>

#define _CRT_SECURE_NO_WARNINGS
#define ll                long long int
#define ld                long double
#define neig(a, u, e, v) for(int v, e = a.head[u] ; ~e and (v = a.to[e], 1) ; e = a.nxt[e])
#define EPS            1e-9
#define all(v)            v.begin(),v.end()
#define X                first
#define Y                second
#define ii pair<int,int>

using namespace std;

ll MOD = 1e9 + 7;

const int N = 15, M = 1e5 + 10, NM1 = N - 1;
ll OO = 1e18 + 8;
int oo = 1e9 + 8;

void readFile() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen ("output.txt","w",stdout);
#endif
}

struct DSU {
    vector<int> par, sz;

    DSU(int n) { par.resize(n), sz.resize(n), iota(all(par), 0), fill(all(sz), 1); }

    int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }

    bool join(int u, int v) {
        int p1 = leader(u), p2 = leader(v);
        if (p1 == p2)return false;
        if (sz[p1] < sz[p2])swap(p1, p2);//p2 is bigger
        par[p2] = p1;
        sz[p1] += sz[p2];
        return true;
    }
} dsu(1);
int n, m, u, v, deg[55];
int main() {
    readFile();
    scanf("%d%d", &n, &m);
    dsu = DSU(n);
    bool ok = 1;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &u, &v);
        deg[--u]++, deg[--v]++;
        if(deg[u] > 2 || deg[v] > 2) ok = 0;
        if(!dsu.join(u, v) && i != n - 1 && i != m - 1) ok = 0;
    }
    if(!ok || n < m) return puts("NO"), 0;
    int cnt = n - m;
    printf("YES\n%d\n", cnt);
    for(int i = 0; i < n && cnt; i++){
        for(int j = i + 1; j < n && cnt && deg[i] < 2; j++){
            while(deg[j] < 2 && cnt && deg[i] < 2){
                printf("%d %d\n", i + 1, j + 1);
                deg[i]++, deg[j]++;
                cnt--;
            }
        }
    }
    return 0;
}


/*
Author: Monem
*/
#include <bits/stdc++.h>

#define _CRT_SECURE_NO_WARNINGS
#define ll                long long int
#define ld                long double
#define neig(a, u, e, v) for(int v, e = a.head[u] ; ~e and (v = a.to[e], 1) ; e = a.nxt[e])
#define EPS            1e-9
#define all(v)            v.begin(),v.end()
#define X                first
#define Y                second
#define ii pair<int,int>

using namespace std;

ll MOD = 1e9 + 7;

const int N = 15, M = 1e5 + 10, NM1 = N - 1;
ll OO = 1e18 + 8;
int oo = 1e9 + 8;

void readFile() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen ("output.txt","w",stdout);
#endif
}

struct DSU {
    vector<int> par, sz;

    DSU(int n) { par.resize(n), sz.resize(n), iota(all(par), 0), fill(all(sz), 1); }

    int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }

    bool join(int u, int v) {
        int p1 = leader(u), p2 = leader(v);
        if (p1 == p2)return false;
        if (sz[p1] < sz[p2])swap(p1, p2);//p2 is bigger
        par[p2] = p1;
        sz[p1] += sz[p2];
        return true;
    }
} dsu(1);
int n, m, u, v, deg[55];
int main() {
    readFile();
    scanf("%d%d", &n, &m);
    dsu = DSU(n);
    bool ok = 1;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &u, &v);
        deg[--u]++, deg[--v]++;
        if(deg[u] > 2 || deg[v] > 2 || (u == v && n != 1)) ok = 0;
        if(!dsu.join(u, v) && i != n - 1) ok = 0;
    }
    if(!ok || n < m) return puts("NO"), 0;
    int cnt = n - m;
    printf("YES\n%d\n", cnt);
    for(int i = 0; i < n && cnt; i++){
        for(int j = i + 1; j < n && cnt && deg[i] < 2; j++){
            while(deg[j] < 2 && cnt && deg[i] < 2){
                printf("%d %d\n", i + 1, j + 1);
                deg[i]++, deg[j]++;
                cnt--;
            }
        }
    }
    return 0;
}


/*
Author: Monem
*/
#include <bits/stdc++.h>

#define _CRT_SECURE_NO_WARNINGS
#define ll                long long int
#define ld                long double
#define neig(a, u, e, v) for(int v, e = a.head[u] ; ~e and (v = a.to[e], 1) ; e = a.nxt[e])
#define EPS            1e-9
#define all(v)            v.begin(),v.end()
#define X                first
#define Y                second
#define ii pair<int,int>

using namespace std;

ll MOD = 1e9 + 7;

const int N = 15, M = 1e5 + 10, NM1 = N - 1;
ll OO = 1e18 + 8;
int oo = 1e9 + 8;

void readFile() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen ("output.txt","w",stdout);
#endif
}

struct DSU {
    vector<int> par, sz;

    DSU(int n) { par.resize(n), sz.resize(n), iota(all(par), 0), fill(all(sz), 1); }

    int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }

    bool join(int u, int v) {
        int p1 = leader(u), p2 = leader(v);
        if (p1 == p2)return false;
        if (sz[p1] < sz[p2])swap(p1, p2);//p2 is bigger
        par[p2] = p1;
        sz[p1] += sz[p2];
        return true;
    }
} dsu(1);

int n, m, u, v, deg[55];

int main() {
    readFile();
    scanf("%d%d", &n, &m);
    dsu = DSU(n);
    bool ok = 1;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        deg[--u]++, deg[--v]++;
        if (deg[u] > 2 || deg[v] > 2 || (u == v && n != 1)) ok = 0;
        if (!dsu.join(u, v) && i != n - 1) ok = 0;
    }
    if (!ok || n < m) return puts("NO"), 0;
    int cnt = n - m;
    printf("YES\n%d\n", cnt);
    for (int i = 0; i < n && cnt; i++) {
        for (int k = 0; k < 2; k++) {
            for (int j = i + 1; j < n && cnt && deg[i] < 2; j++) {
                if (deg[j] < 2 && deg[i] < 2 && dsu.join(i, j)) {
                    printf("%d %d\n", i + 1, j + 1);
                    deg[i]++, deg[j]++;
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
        while (deg[i] < 2) {
            printf("%d ", i + 1);
            deg[i]++;
        }
    return 0;
}


/*
Author: Monem
*/
#include <bits/stdc++.h>

#define _CRT_SECURE_NO_WARNINGS
#define ll                long long int
#define ld                long double
#define neig(a, u, e, v) for(int v, e = a.head[u] ; ~e and (v = a.to[e], 1) ; e = a.nxt[e])
#define EPS            1e-9
#define all(v)            v.begin(),v.end()
#define X                first
#define Y                second
#define ii pair<int,int>

using namespace std;

ll MOD = 1e9 + 7;

const int N = 15, M = 1e5 + 10, NM1 = N - 1;
ll OO = 1e18 + 8;
int oo = 1e9 + 8;

void readFile() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen ("output.txt","w",stdout);
#endif
}

struct DSU {
    vector<int> par, sz;

    DSU(int n) { par.resize(n), sz.resize(n), iota(all(par), 0), fill(all(sz), 1); }

    int leader(int u) { return (par[u] == u) ? u : par[u] = leader(par[u]); }

    bool join(int u, int v) {
        int p1 = leader(u), p2 = leader(v);
        if (p1 == p2)return false;
        if (sz[p1] < sz[p2])swap(p1, p2);//p2 is bigger
        par[p2] = p1;
        sz[p1] += sz[p2];
        return true;
    }
} dsu(1);
int n, m, u, v, deg[55];
int main() {
    readFile();
    scanf("%d%d", &n, &m);
    dsu = DSU(n);
    bool ok = 1;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &u, &v);
        deg[--u]++, deg[--v]++;
        if(deg[u] > 2 || deg[v] > 2) ok = 0;
        if(!dsu.join(u, v) && i != n - 1 && i != m - 1) ok = 0;
    }
    if(!ok || n < m) return puts("NO"), 0;
    int cnt = n - m;
    printf("YES\n%d\n", cnt);
    for(int i = 0; i < n && cnt; i++){
        for(int j = i + 1; j < n && cnt && deg[i] < 2; j++){
            if(deg[j] < 2 && cnt){
                printf("%d %d\n", i + 1, j + 1);
                deg[i]++, deg[j]++;
                cnt--;
            }
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
static const int MAXN=50;
int fa[MAXN+10],deg[MAXN+10];
int n,m;
bool flag;
int find(int x)
{
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        deg[u]++,deg[v]++;
        if(find(u)==find(v)) flag=true;
        fa[fa[u]]=fa[v];
    }
    bool flag1=true;
    for(int i=1;i<=n;i++) if(deg[i]!=2) flag1=false;
    for(int i=2;i<=n;i++) if(find(i)!=find(1)) flag1=false;
    if(flag1)
    {
        cout<<"YES"<<endl<<0<<endl;
        return 0;
    }
    bool flag2=false;
    for(int i=1;i<=n;i++) if(deg[i]>2) flag2=true;
    if(flag2 || m>=n || flag)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl<<n-m<<endl;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(deg[i]<2 && deg[j]<2 && find(i)!=find(j))
            {
                fa[fa[i]]=fa[j];
                deg[i]++,deg[j]++;
                cout<<i<<" "<<j<<endl;
            }
    for(int i=1;i<=n;i++)
        if(deg[i]<2)
        {
            cout<<i<<" ";
            break;
        }
    for(int i=n;i>=1;i--)
        if(deg[i]<2)
        {
            cout<<i<<endl;;
            break;
        }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

class dsu {
 public:
  int n;
  vector<int> p;

  dsu(int n) : n(n) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }

  int get(int x) {
    return x == p[x] ? x : p[x] = get(p[x]);
  }

  inline bool unite(int x, int y) {
    x = get(x);
    y = get(y);
    if (x != y) {
      p[x] = y;
      return true;
    }
    return false;
  }
};

int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  if (m > n) {
    puts("NO");
    return 0;
  }
  vector<int> a(n);
  dsu ds(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    --x; --y;
    ++a[x]; ++a[y];
    if (ds.get(x) == ds.get(y) && i != n - 1) {
      puts("NO");
      return 0;
    }
    ds.unite(x, y);
  }
  for (int i = 0; i < n; ++i) {
    if (a[i] > 2) {
      puts("NO");
      return 0;
    }
  }
  puts("YES");
  printf("%d\n", n - m);
  for (int i = 0; i < n; ++i) {
    while (a[i] < 2) {
      int t = i + (n != 1);
      for (int j = t; j < n; ++j) {
        if (a[j] < 2 && (n <= 2 || m + 1 == n || ds.get(i) != ds.get(j))) {
          printf("%d %d\n", i + 1, j + 1);
          ++m;
          ++a[i]; ++a[j];
          ds.unite(i, j);
          break;
        }
      }
    }
  }
  return 0;
}


#pragma warning(disable:4996)
#include <bits\stdc++.h>
using namespace std;

//============================================================================================
#define p(a) ((a) * (a))
#define forn(i, n, s) for (int i = s; i < n; ++i)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<ll, ll> p2ll;
typedef pair<string, int> psi;
//============================================================================================

const int MAX = 50;
int n, m, poss;
vector<pii> os;
bool visited[MAX];
bool hasCircle;
int graph[MAX][MAX];

inline void dfs(int u, int f) {
	visited[u] = true;

	forn(v, n, 0) {
		if ((v != f && graph[u][v] > 0) || graph[u][v] == 2) {
			if (visited[v]) {
				hasCircle = true;
			}
			else {
				dfs(v, u);
			}
		}
	}
}

inline bool check() {
	forn(i, n, 0) {
		int cou = accumulate(graph[i], graph[i] + n, 0);

		if (cou > 2) {
			return false;
		}
	}

	hasCircle = false;
	memset(visited, false, sizeof visited);
	poss = 0;

	forn(i, n, 0) {
		if (!visited[i]) {
			++poss;
			dfs(i, -1);
		}
	}

	if (poss > 1 && hasCircle) {
		return false;
	}

	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	//freopen("input.txt", "rt", stdin);

	cin >> n >> m;

	if (n == 2 && !m) {
		cout << "YES" << endl << 2 << endl;
		forn(i, 2, 0) {
			cout << "1 2" << endl;
		}

		return 0;
	}

	pii is;
	forn(i, m, 0) {
		cin >> is.first >> is.second;
		--is.first, --is.second;
		++graph[is.first][is.second], ++graph[is.second][is.first];
	}

	if (!check()) {
		cout << "NO";
		return 0;
	}

	forn(i, n, 0) {
		forn(j, n, i) {
			++graph[i][j], ++graph[j][i];

			if (check()) {
				os.push_back(make_pair(i, j));
			}
			else {
				--graph[i][j], --graph[j][i];
			}
		}
	}

	cout << "YES" << endl << os.size() << endl;
	forn(i, os.size(), 0) {
		cout << os[i].first + 1 << ' ' << os[i].second + 1 << endl;
	}

	return 0;
}


#pragma warning(disable:4996)
#include <bits\stdc++.h>
using namespace std;

//============================================================================================
#define p(a) ((a) * (a))
#define forn(i, n, s) for (int i = s; i < n; ++i)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<ll, ll> p2ll;
typedef pair<string, int> psi;
//============================================================================================

const int MAX = 50;
int n, m, poss;
vector<pii> data_, os;
vector<bool> visited;
bool hasCircle;
int graph[MAX][MAX];

inline void dfs(int u, int f) {
	visited[u] = true;

	forn(v, n, 0) {
		if ((v != f && graph[u][v] > 0) || graph[u][v] == 2) {
			if (visited[v]) {
				hasCircle = true;
			}
			else {
				dfs(v, u);
			}
		}
	}
}

inline bool check() {
	forn(i, n, 0) {
		int cou = accumulate(graph[i], graph[i] + n, 0);

		if (cou > 2) {
			return false;
		}
	}

	hasCircle = false;
	visited.resize(MAX, false);
	poss = 0;

	forn(i, n, 0) {
		if (!visited[i]) {
			++poss;
			dfs(i, -1);
		}
	}

	if (poss > 1 && hasCircle) {
		return false;
	}

	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	//freopen("input.txt", "rt", stdin);

	cin >> n >> m;

	if (n == 2 && !m) {
		cout << "YES" << endl << 2 << endl;
		forn(i, 2, 0) {
			cout << "1 2" << endl;
		}

		return 0;
	}

	pii is;
	forn(i, m, 0) {
		cin >> is.first >> is.second;
		data_.push_back(is);
		--is.first, --is.second;
		++graph[is.first][is.second], ++graph[is.second][is.first];
	}

	if (!check()) {
		cout << "NO";
		return 0;
	}

	forn(i, n, 0) {
		forn(j, n, i) {
			++graph[i][j], ++graph[j][i];

			if (check()) {
				os.push_back(make_pair(i, j));
			}
			else {
				--graph[i][j], --graph[j][i];
			}
		}
	}

	cout << "YES" << endl << os.size() << endl;
	forn(i, os.size(), 0) {
		cout << os[i].first + 1 << ' ' << os[i].second + 1 << endl;
	}

	return 0;
}


#pragma warning(disable:4996)
#include <bits\stdc++.h>
using namespace std;

//============================================================================================
#define p(a) ((a) * (a))
#define forn(i, n, s) for (int i = s; i < n; ++i)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<ll, ll> p2ll;
typedef pair<string, int> psi;
//============================================================================================

const int MAX = 51;
int n, m, poss;
vector<pii> data_, os;
vector<bool> visited;
bool hasCircle;
int graph[MAX][MAX];

inline void dfs(int u, int f) {
	visited[u] = true;

	forn(v, n, 0) {
		if ((v != f && graph[u][v] > 0) || graph[u][v] == 2) {
			if (visited[v]) {
				hasCircle = true;
			}
			else {
				dfs(v, u);
			}
		}
	}
}

inline bool check() {
	forn(i, n, 0) {
		int cou = accumulate(graph[i], graph[i] + n, 0);

		if (cou > 2) {
			return false;
		}
	}

	hasCircle = false;
	visited.resize(MAX, false);
	poss = 0;

	forn(i, n, 0) {
		if (!visited[i]) {
			++poss;
			dfs(i, -1);
		}
	}

	if (poss > 1 /*&& hasCircle*/) {
		return false;
	}

	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	//freopen("input.txt", "rt", stdin);

	cin >> n >> m;

	if (n == 2 && !m) {
		cout << "YES" << endl << 2 << endl;
		forn(i, 2, 0) {
			cout << "1 2" << endl;
		}

		return 0;
	}

	pii is;
	forn(i, m, 0) {
		cin >> is.first >> is.second;
		data_.push_back(is);
		--is.first, --is.second;
		++graph[is.first][is.second], ++graph[is.second][is.first];
	}

	if (!check()) {
		cout << "NO";
		return 0;
	}

	forn(i, n, 0) {
		forn(j, n, i) {
			++graph[i][j], ++graph[j][i];

			if (check()) {
				os.push_back(make_pair(i, j));
			}
			else {
				--graph[i][j], --graph[j][i];
			}
		}
	}

	cout << "YES" << endl << os.size() << endl;
	forn(i, os.size(), 0) {
		cout << os[i].first + 1 << ' ' << os[i].second + 1 << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define pf printf
#define sf scanf
using namespace std;
typedef long long ll;
const int N=5050;
int fa[100],a[60][60],t[60][60],v[100];
int find(int x)
{
    if(x==fa[x])
    {
        return x;
    }
    return fa[x]=find(fa[x]);
}
int n ,m,x,y;
struct node
{
    int x,y;
}ans[100];
bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
set<int> st;
int main()
{
    //freopen("data.txt","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        fa[i]=i;
    int k=1,kk=0;
    if(n==m)
        kk=1;
    for(int i=1;i<=m;++i)
    {
        sf("%d%d",&x,&y);
        if(x>y)
            swap(x,y);
        int fx=find(x);
        int fy=find(y);
        if(fx==fy&&kk==1)
        {
            kk=0;
            v[x]++;
            v[y]++;
            if(v[x]>2||v[y]>2)
                k=0;
            continue;
        }
        if(fx==fy&&kk==0)
            k=0;
        v[x]++;
        v[y]++;
        if(v[x]>2||v[y]>2)
            k=0;
        fa[fy]=fx;
    }
    if(n==m&&n==1)
    {
        puts("YES");
        puts("0");
        return 0;
    }
    if(k==0)
    {
        puts("NO");
        return 0;
    }
    puts("YES");
   /* for(int i=1;i<=9;++i)
        cout<<find(i)<<" ";
    puts("");*/
    int l,r,dd=0,u=0;
    for(int i=1;i<=n;++i)
    {
        if(v[i]<2)
        {
            if(st.size()==0)
                st.insert(i);
            else
            {
                int t=0;
                for(set<int>::iterator it=st.begin();it!=st.end();++it)
                {
                    int fx=find(*it);
                    int fy=find(i);
                    if(fx==fy)
                        continue;
                    else
                    {
                        fa[fy]=fx;
                        t=1;
                        ans[++u].x=min(*it,i);
                        ans[u].y=max(*it,i);
                        v[i]++;
                        v[*it]++;
                        if(v[i]<2)
                            st.insert(i);
                        if(v[*it]==2)
                            st.erase(it);
                        break;
                    }
                }
                if(t==0&&v[i]<2)
                    st.insert(i);
            }

        }
    }
    if(st.size())
        ans[++u].x=*st.begin(),ans[u].y=*--st.end();
    sort(ans+1,ans+1+u,cmp);
    cout<<n-m<<endl;
    for(int i=1;i<=u;++i)
    {
        cout<<ans[i].x<<" "<<ans[i].y<<endl;
    }
	return 0;
}


#include<bits/stdc++.h>
#define pf printf
#define sf scanf
using namespace std;
typedef long long ll;
const int N=5050;
int fa[100],a[60][60],t[60][60],v[100];
int find(int x)
{
    if(x==fa[x])
    {
        return x;
    }
    return fa[x]=find(fa[x]);
}
int n ,m,x,y;
struct node
{
    int x,y;
}ans[100];
bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
set<int> st;
int main()
{
    //freopen("data.txt","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        fa[i]=i;
    int k=1,kk=0;
    if(n==m)
        kk=1;
    for(int i=1;i<=m;++i)
    {
        sf("%d%d",&x,&y);
        if(x>y)
            swap(x,y);
        int fx=find(x);
        int fy=find(y);
        if(fx==fy&&kk==1)
        {
            kk=0;
            v[x]++;
            v[y]++;
            if(v[x]>2||v[y]>2)
                k=0;
            continue;
        }
        if(fx==fy&&kk==0)
            k=0;
        v[x]++;
        v[y]++;
        if(v[x]>2||v[y]>2)
            k=0;
        fa[y]=fx;
    }
    if(n==m&&n==1)
    {
        puts("YES");
        puts("0");
        return 0;
    }
    if(k==0)
    {
        puts("NO");
        return 0;
    }
    puts("YES");

    int l,r,dd=0,u=0;
    for(int i=1;i<=n;++i)
    {
        if(v[i]<2)
        {
            if(st.size()==0)
                st.insert(i);
            else
            {
                int t=0;
                for(set<int>::iterator it=st.begin();it!=st.end();++it)
                {
                    int fx=find(*it);
                    int fy=find(i);
                    if(fx==fy)
                        continue;
                    else
                    {
                        fa[i]=fx;
                        t=1;
                        ans[++u].x=min(*it,i);
                        ans[u].y=max(*it,i);
                        v[i]++;
                        v[*it]++;
                        if(v[i]<2)
                            st.insert(i);
                        if(v[*it]==2)
                            st.erase(it);
                        break;
                    }
                }
                if(t==0&&v[i]<2)
                    st.insert(i);
            }

        }
    }
    if(st.size())
        ans[++u].x=*st.begin(),ans[u].y=*--st.end();
    sort(ans+1,ans+1+u,cmp);
    cout<<n-m<<endl;
    for(int i=1;i<=u;++i)
    {
        cout<<ans[i].x<<" "<<ans[i].y<<endl;
    }
	return 0;
}


#include<bits/stdc++.h>
#define pf printf
#define sf scanf
using namespace std;
typedef long long ll;
const int N=5050;
int fa[100],a[60][60],t[60][60],v[100];
int find(int x)
{
    if(x==fa[x])
    {
        return x;
    }
    return fa[x]=find(fa[x]);
}
int n ,m,x,y;
struct node
{
    int x,y;
}ans[100];
bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
set<int> st;
int main()
{
    //freopen("data.txt","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        fa[i]=i;
    int k=1;
    for(int i=1;i<=m;++i)
    {
        sf("%d%d",&x,&y);
        if(x>y)
            swap(x,y);
        int fx=find(x);
        int fy=find(y);
        if(fx==fy)
        {
            k=0;
        }
        v[x]++;
        v[y]++;
        if(v[x]>2||v[y]>2)
            k=0;
        fa[y]=fx;
    }
    if(k==0)
    {
        puts("NO");
        return 0;
    }
    puts("YES");
    int l,r,dd=0,u=0;
    for(int i=1;i<=n;++i)
    {
        if(v[i]<2)
        {
            if(st.size()==0)
                st.insert(i);
            else
            {
                int t=0;
                for(set<int>::iterator it=st.begin();it!=st.end();++it)
                {
                    int fx=find(*it);
                    int fy=find(i);
                    if(fx==fy)
                        continue;
                    else
                    {
                        fa[i]=fx;
                        t=1;
                        ans[++u].x=min(*it,i);
                        ans[u].y=max(*it,i);
                        v[i]++;
                        v[*it]++;
                        if(v[i]<2)
                            st.insert(i);
                        if(v[*it]==2)
                            st.erase(it);
                        break;
                    }
                }
                if(t==0&&v[i]<2)
                    st.insert(i);
            }

        }
    }
    if(st.size())
        ans[++u].x=*st.begin(),ans[u].y=*--st.end();
    sort(ans+1,ans+1+u,cmp);
    cout<<n-m<<endl;
    for(int i=1;i<=u;++i)
    {
        cout<<ans[i].x<<" "<<ans[i].y<<endl;
    }
	return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    set<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.insert(i);
    }
    while (cur.size() >= 2) {
        int v = *cur.begin();
        cur.erase(v);
        int u = *cur.begin();
        cur.erase(u);
        deg[v]++;
        deg[u]++;
        if (deg[v] == 1)
            cur.insert(v);
        if (deg[u] == 1)
            cur.insert(u);
        ans.push_back({v, u});
    }
    if (cur.size() == 1) {
        int v = *cur.begin();
        ans.push_back({v, v});
    }
    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1<<' ' << u.second + 1 << '\n';
    return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<stdio.h>
#include<string.h>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
int cmp=0;
vector<int> parent, rank1;
void make_set (int v) {
    parent[v] = v;
    rank1[v] = 0;
}

int find_set (int v) {
    if (v == parent[v])
        return v;
    return parent[v] = find_set (parent[v]);
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (rank1[a] < rank1[b])
            swap (a, b);
        parent[b] = a;
        if (rank1[a] == rank1[b])
            ++rank1[a];
    }
}
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            union_sets(v, to), dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    parent.resize(n);
    rank1.resize(n);
    for (int i = 0; i < n; ++i)
        make_set(i);
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);

    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    memset(used, 0, sizeof(used));
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            dfs(i);
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    vector<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.push_back(i);
    }
    for (int i = 0; i < n; ++i) {
        if (!used[i]) {
            dfs(i);
            cmp++;
        }
    }
    vector<int> nd;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if(deg[i]>=2||deg[j]>=2)
                continue;
            if (find_set(i) != find_set(j)) {
                ans.push_back({i, j});
                deg[i]++;
                deg[j]++;
                union_sets(i, j);
            }
        }
    }

   for(int i=0;i<n;++i)
   {
       if(deg[i]<=1)
           nd.push_back(i);
   }
    ans.push_back({nd[0], nd[nd.size() - 1]});

    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1 << ' ' << u.second + 1 << '\n';
    return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<stdio.h>
#include<string.h>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
int cmp=0;
vector<int> parent, rank1;
void make_set (int v) {
    parent[v] = v;
    rank1[v] = 0;
}

int find_set (int v) {
    if (v == parent[v])
        return v;
    return parent[v] = find_set (parent[v]);
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (rank1[a] < rank1[b])
            swap (a, b);
        parent[b] = a;
        if (rank1[a] == rank1[b])
            ++rank1[a];
    }
}
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            union_sets(v, to), dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    parent.resize(n);
    rank1.resize(n);
    for (int i = 0; i < n; ++i)
        make_set(i);
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);

    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    memset(used, 0, sizeof(used));
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            dfs(i);
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    vector<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.push_back(i);
    }
    for (int i = 0; i < n; ++i) {
        if (!used[i]) {
            dfs(i);
            cmp++;
        }
    }
    vector<int> nd;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (find_set(i) != find_set(j)) {
                ans.push_back({i, j});
                deg[i]++;
                deg[j]++;
                union_sets(i, j);
            }
        }
    }

   for(int i=0;i<n;++i)
   {
       if(deg[i]<=1)
           nd.push_back(i);
   }
    ans.push_back({nd[0], nd[nd.size() - 1]});

    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1 << ' ' << u.second + 1 << '\n';
    return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<stdio.h>
#include<string.h>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
int cmp=0;
vector<int> parent, rank1;
void make_set (int v) {
    parent[v] = v;
    rank1[v] = 0;
}

int find_set (int v) {
    if (v == parent[v])
        return v;
    return parent[v] = find_set (parent[v]);
}

void union_sets (int a, int b) {
    a = find_set (a);
    b = find_set (b);
    if (a != b) {
        if (rank1[a] < rank1[b])
            swap (a, b);
        parent[b] = a;
        if (rank1[a] == rank1[b])
            ++rank1[a];
    }
}
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            union_sets(v, to), dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    parent.resize(n);
    rank1.resize(n);
    for (int i = 0; i < n; ++i)
        make_set(i);
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);

    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    memset(used, 0, sizeof(used));
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            dfs(i);
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    vector<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        if (!used[i]) {
            dfs(i);
            cmp++;
        }
    }
    vector<int> nd;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (find_set(i) != find_set(j)) {
                ans.push_back({i, j});
                union_sets(i, j);
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.push_back(i);
    }
    ans.push_back({nd[0], nd[nd.size() - 1]});

    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1 << ' ' << u.second + 1 << '\n';
    return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);

    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    memset(used, 0, sizeof(used));
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            dfs(i);
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    set<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.insert(i);
    }
    while (cur.size() >= 2) {
        int v = *cur.begin();
        cur.erase(v);
        int u = *cur.begin();
        cur.erase(u);
        deg[v]++;
        deg[u]++;
        if (deg[v] == 1)
            cur.insert(v);
        if (deg[u] == 1)
            cur.insert(u);
        ans.push_back({v, u});
    }
    if (cur.size() == 1) {
        int v = *cur.begin();
        ans.push_back({v, v});
    }
    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1<<' ' << u.second + 1 << '\n';
    return 0;
}


#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include <vector>
#include<stdio.h>
#include<string.h>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
int used[100];
vector<vector<int>> g;
bool ok=1;
void dfs(int v, int p=-1) {
    used[v] = 1;
    for (auto to:g[v]) {
        if (!used[to])
            dfs(to, v);
        else {
            if (to != p)
                ok = 0;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;
    g.resize(n);
    bool ok1 = 1, ok2 = 1, ok3 = 1;
    bool ok4 = 1;
    if (m > n)
        ok1 = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
        if (g[a].size() > 2 || g[b].size() > 2) {
            ok2 = 0;
        }
    }
    dfs(0);

    for (int i = 0; i < n; ++i) {
        if (!used[i])
            ok3 = 0;
        if (g[i].size() != 2)
            ok4 = 0;
    }
    if (ok4 && ok3) {
        cout << "YES" << endl << 0;
        return 0;
    }
    memset(used, 0, sizeof(used));
    for (int i = 0; i < n; ++i) {
        if (!used[i])
            dfs(i);
    }
    if (!(ok1 && ok2 && ok)) {
        cout << "NO";
        return 0;
    }

    vector<pair<int, int>> ans;
    set<int> cur;
    vector<int> deg(n);
    for (int i = 0; i < n; ++i) {
        deg[i] = g[i].size();
        if (deg[i] <= 1)
            cur.insert(i);
    }
    while (cur.size() >= 2) {
        int v = *cur.begin();
        cur.erase(v);
        int u = *cur.begin();
        cur.erase(u);
        deg[v]++;
        deg[u]++;
        if (deg[v] == 1)
            cur.insert(v);
        if (deg[u] == 1)
            cur.insert(u);
        ans.push_back({v, u});
    }
    if (cur.size() == 1) {
        int v = *cur.begin();
        ans.push_back({v, v});
    }
    cout << "YES\n" << ans.size() << '\n';
    for (auto u:ans)
        cout << u.first + 1<<' ' << u.second + 1 << '\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 52;
int pa[maxn];
int e1[maxn*maxn],e2[maxn*maxn];
int d[maxn];
vector<pair<int,int> > ans;
int fi(int x)
{
    if(pa[x]==x)return x;
    return pa[x]=fi(pa[x]);
}
void uni(int x,int y)
{
    int p1 = fi(x),p2 = fi(y);
    if(p1==p2)return;
    pa[p2]=p1;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)pa[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&e1[i],&e2[i]);
    for(int i=1;i<=m;i++)
    {
        uni(e1[i],e2[i]);
        d[e1[i]]++,d[e2[i]]++;
        if(d[e1[i]]>2||d[e2[i]]>2)return puts("NO"),0;
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(d[j]<=1&&d[i]<=1&&fi(i)!=fi(j))
            {
                ans.push_back(make_pair(j,i));
                uni(i,j);
                d[i]++,d[j]++;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(d[i]==2)continue;
        for(int j=1;j<i;j++)
        {
            if(d[j]==1)
            {
                ans.push_back(make_pair(j,i));
                uni(i,j);
                d[i]++,d[j]++;
            }
        }
    }
    for(int i=1;i<=n;i++)
        if(d[i]==0)ans.push_back(make_pair(i,i));
    int p = fi(1);
    for(int i=1;i<=n;i++)
        if(fi(i)!=p)return puts("NO"),0;
    puts("YES");
    sort(ans.begin(),ans.end());
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
}


#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <set>
#include <map>
#include <unordered_set>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
int n, m;
const int mxn = 52;
int p[mxn], d[mxn];
int find(int x) {
	if (x == p[x]) return x;
	return p[x] = find(p[x]);
}
void uni(int x, int y) {
	int px = find(x), py = find(y);
	if (px == py) return;
	p[py] = px;
}
int main() {
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin >> n >> m;
	vector<pair<int, int>> res;
	for (int i = 1; i <= n; ++i) {
		p[i] = i;
	}
	for (int i = 1; i <= m; ++i) {
		//cout << i << ',' << '\n';
		int x, y;
		cin >> x >> y;
		uni(x, y);
		++d[x];
		++d[y];
		//cout << d[x] << ',' << d[y] << '\n';
		if (d[x] > 2 || d[y] > 2) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j < i; ++j) {
			if (d[i] <= 1 && d[j] <= 1 && find(i) != find(j)) {
				uni(i, j);
				++d[i], ++d[j];
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 2) continue;
		for (int j = 1; j < i; ++j) {
			if (d[j] == 1 && find(i) != find(j)) {
				uni(i, j);
				++d[i], ++d[j];
				//cout << j << ',' << i << '\n';
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 0) {
			res.push_back({i, i});
		}
	}
	int root = find(1);
	for (int i = 1; i <= n; ++i) {
		if (find(i) != root) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	cout << "YES" << '\n';
	cout << res.size() << '\n';
	sort(begin(res), end(res));
	for (auto i : res) {
		cout << i.first << ' ' << i.second << '\n';
	}
	return 0;//version0
}


#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <set>
#include <map>
#include <unordered_set>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
int n, m;
const int mxn = 52;
int p[mxn], d[mxn];
int find(int x) {
	if (x == p[x]) return x;
	return p[x] = find(p[x]);
}
void uni(int x, int y) {
	int px = find(x), py = find(y);
	if (px == py) return;
	p[py] = px;
}
int main() {
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin >> n >> m;
	vector<pair<int, int>> res;
	for (int i = 1; i <= n; ++i) {
		p[i] = i;
	}
	for (int i = m; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		uni(x, y);
		++d[x];
		++d[y];
		if (d[x] > 2 || d[y] > 2) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j < i; ++j) {
			if (d[i] <= 1 && d[j] <= 1 && find(i) != find(j)) {
				uni(i, j);
				++d[i], ++d[j];
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 2) continue;
		for (int j = 1; j < i; ++j) {
			if (d[j] == 1 && find(i) != find(j)) {
				uni(i, j);
				++d[i], ++d[j];
				//cout << j << ',' << i << '\n';
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 0) {
			res.push_back({i, i});
		}
	}
	int root = find(1);
	for (int i = 1; i <= n; ++i) {
		if (find(i) != root) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	cout << "YES" << '\n';
	cout << res.size() << '\n';
	sort(begin(res), end(res));
	for (auto i : res) {
		cout << i.first << ' ' << i.second << '\n';
	}
	return 0;//version0
}


#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <set>
#include <map>
#include <unordered_set>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
int n, m;
const int mxn = 52;
//int e1[mxn * mxn], e2[mxn * mxn];
int p[mxn], d[mxn];
int find(int x) {
	if (x != p[x]) {
		p[x] = find(p[x]);
	}
	return p[x];
}
void uni(int x, int y) {
	int px = find(x), py = find(y);
	if (px == py) return;
	p[py] = px;
	return;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin >> n >> m;
	vector<pair<int, int>> res;
	for (int i = 1; i <= n; ++i) {
		p[i] = i;
	}
	for (int i = 1; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		uni(x, y);
		++d[x], ++d[y];
		if (d[x] > 2 || d[y] > 2) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j < i; ++j) {
			if (d[i] <= 1 && d[j] <= 1 && find(i) != find(j)) {
				uni(i, j);
				++d[i], ++d[j];
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 2) {
			continue;
		}
		for (int j = 1; j < i; ++j) {
			if (d[j] == 1) {
				uni(i, j);
				++d[i], ++d[j];
				res.push_back({j, i});
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		if (d[i] == 0) {
			res.push_back({i, i});
		}
	}
	int root = find(1);
	for (int i = 1; i <= n; ++i) {
		if (find(i) != root) {
			cout << "NO" << '\n';
			return 0;
		}
	}
	sort(begin(res), end(res));
	cout << "YES" << '\n';
	cout << res.size() << '\n';
	for (auto i : res) {
		cout << i.first << ' ' << i.second << '\n';
	}
	return 0;//version0
}


/*
 ID: jiguowe2
 TASK: sprime
 LANG: C++14
 */

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

int find(vector<int> &par, int x)
{
    if(par[x] == x)
        return x;

    return par[x] = find(par, par[x]);
}

void connect(vector<int> &par, int x, int y)
{
    int p1 = find(par, x);
    int p2 = find(par, y);
    if(p1 != p2)
        par[p1] = p2;
}

int main() {
    int n, m, x, y;
    cin >> n >> m;

    vector<pair<int, int>> ans;
    vector<int> degree(n+1, 0);
    vector<int> par(n+1, 0);
    for(int i=1; i<=n; ++i)
        par[i] = i;

    for(int i=0; i<m; ++i) {
        cin >> x >> y;
        ++degree[x];
        ++degree[y];
        connect(par, x, y);

        if(degree[x] > 2 || degree[y] > 2) {
            cout << "NO" << endl;
            return 0;
        }
    }

    for(int i=1; i<n; ++i) {
        for(int j=i+1; j<=n; ++j) {
            if(degree[i] <= 1 && degree[j] <= 1 && find(par, i) != find(par, j)) {
                ans.push_back(make_pair(i, j));
                connect(par, i, j);
                ++degree[i];
                ++degree[j];
            }
        }
    }

    for(int i=1; i<=n; ++i) {
        if(degree[i] == 2)
            continue;

        for(int j=i+1; j<=n; ++j) {
            if(degree[j] == 1) {
                ans.push_back(make_pair(i, j));
                connect(par, i, j);
                ++degree[i];
                ++degree[j];
            }
        }
    }

    for(int k=1; k<=n; ++k) {
        if(degree[k] == 0)
            ans.push_back(make_pair(k, k));
    }

    int p = find(par, 1);
    for(int k=1; k<=n; ++k) {
        if(find(par, k) != p) {
            cout << "NO" << endl;
            return 0;
        }
    }

    cout << "YES" << endl;
    sort(ans.begin(), ans.end());
    cout << ans.size() << endl;
    for(int i=0; i<ans.size(); ++i)
        cout << ans[i].first << " " << ans[i].second << endl;

    return 0;
}


/*
 ID: jiguowe2
 TASK: sprime
 LANG: C++14
 */

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

int find(vector<int> &par, int x)
{
    if(par[x] == x)
        return x;

    return par[x] = find(par, par[x]);
}

void connect(vector<int> &par, int x, int y)
{
    int p1 = find(par, x);
    int p2 = find(par, y);
    if(p1 != p2)
        par[p1] = p2;
}

int main() {
    int n, m, x, y;
    cin >> n >> m;

    vector<pair<int, int>> ans;
    vector<int> degree(n+1, 0);
    vector<int> par(n+1, 0);
    for(int i=1; i<=n; ++i)
        par[i] = i;

    for(int i=0; i<m; ++i) {
        cin >> x >> y;
        ++degree[x];
        ++degree[y];
        connect(par, x, y);

        if(degree[x] > 2 || degree[y] > 2) {
            cout << "NO" << endl;
            return 0;
        }
    }

    for(int i=1; i<n; ++i) {
        for(int j=i+1; j<=n; ++j) {
            if(degree[i] <= 1 && degree[j] <= 1 && find(par, i) != find(par, j)) {
                ans.push_back(make_pair(i, j));
                connect(par, i, j);
                ++degree[i];
                ++degree[j];
            }
        }
    }

    for(int i=1; i<=n; ++i) {
        if(degree[i] == 2)
            continue;

        for(int j=i+1; j<=n; ++j) {
            if(degree[j] == 1)
                ans.push_back(make_pair(i, j));
            connect(par, i, j);
            ++degree[i];
            ++degree[j];
        }
    }

    for(int k=1; k<=n; ++k) {
        if(degree[k] == 0)
            ans.push_back(make_pair(k, k));
    }

    int p = find(par, 1);
    for(int k=1; k<=n; ++k) {
        if(find(par, k) != p) {
            cout << "NO" << endl;
            return 0;
        }
    }

    cout << "YES" << endl;
    sort(ans.begin(), ans.end());
    cout << ans.size() << endl;
    for(int i=0; i<ans.size(); ++i)
        cout << ans[i].first << " " << ans[i].second << endl;

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 60 };

class UFDS
{
private:
    std::vector<int> size, ps;
    int count;

public:
    UFDS(int N) : size(N + 1, 1), ps(N + 1), count(N)
    {
        std::iota(ps.begin(), ps.end(), 0);
    }

    int find_set(int x) const
    {
        return x == ps[x] ? x : find_set(ps[x]);
    }

    bool same_set(int x, int y)
    {
        return find_set(x) == find_set(y);
    }

    void union_set(int x, int y)
    {
        if (same_set(x, y))
            return;

        int p = find_set(x);
        int q = find_set(y);

        if (size[p] < size[q])
            std::swap(p, q);

        ps[q] = p;
        size[p] += size[q];
        --count;
    }

    int cc() const { return count; };
};

vector<int> adj[MAX];
bitset<MAX> dfs_stack, visited;

bool dfs(int u, int p)
{
    if (visited[u])
        return false;

    visited[u] = true;
    dfs_stack[u] = true;

    for (auto v : adj[u])
    {
        if (v != p and dfs_stack[v])
            return true;

        if (dfs(v, u))
            return true;
    }

    dfs_stack[u] = false;

    return false;
}

bool has_cycle(int N)
{
    for (int u = 1; u <= N; ++u)
        if (not visited[u])
            if (dfs(u, u))
                return true;

    return false;
}

pair<string, vector<ii>> solve(int N, int M)
{
    int d2 = 0, autoloop = 0;

    UFDS ufds(N);

    for (int u = 1; u <= N; ++u)
    {
        if (adj[u].size() == 2ul)
            d2++;

        // Cada vértice deve ter, no máximo, dois vizinhos
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        for (auto v : adj[u])
        {
            ufds.union_set(u, v);
            autoloop += (u == v ? 1 : 0);
        }
    }

    // Se for connectado e grau = 2 todos, ok
    if (ufds.cc() == 1 and d2 == N)
        return { "YES", {} };

    // Se tiver mais de N arestas ou tiver um ciclo, não é possível
    if (M > N or has_cycle(N) or autoloop)
        return { "NO", {} };

    vector<ii> ans;

    for (int u = 1; u <= N; ++u)
    {
        for (int v = u + 1; v <= N; ++v)
        {
            if (adj[u].size() == 2ul)
                break;

            if (adj[v].size() < 2ul and ufds.same_set(u, v) == false)
            {
                ufds.union_set(u, v);
                adj[u].push_back(v);
                adj[v].push_back(u);
                ans.push_back(ii(u, v));
            }
        }
    }

    vector<int> rs;

    for (int u = 1; u <= N; ++u)
        if (adj[u].size() == 1ul)
            rs.push_back(u);

    LOGV(rs, endl);

    if (rs.empty())
    {
        if (N == 1)
            return { "YES", { { 1, 1 } } };
        else
            return { "NO", {} };
    }

    ans.push_back(ii(rs.front(), rs.back()));

//    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    set<ii> es;

    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N, M);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

vector<int> adj[MAX];
bitset<MAX> found;

void dfs(int u, int p, int& w)
{
    if (found[u])
        return;

    found[u] = true;

    if (adj[u].size() == 1ul and u != p)
    {
        w = u;
        return;
    }

    for (auto v : adj[u])
        dfs(v, p, w);
}

pair<string, vector<ii>> solve(int N)
{
    vector<ii> xs;
    vector<int> ys;

    for (int u = 1; u <= N; ++u)
    {
LOG(u, ' '); LOG(adj[u].size(), endl);
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        if (adj[u].empty())
            xs.push_back(ii(u, u));
        else if (adj[u].size() == 1ul)
            ys.push_back(u);
    }

    LOGV(ys, endl);

    for (auto u : ys)
    {
        if (found[u])
            continue;

        int v;
        dfs(u, u, v);

        xs.push_back(ii(u, v));
    }

    sort(xs.begin(), xs.end());

    LOGV(xs, endl);

    vector<ii> ans;

    for (size_t i = 1; i < xs.size(); ++i)
        ans.push_back(ii(xs[i - 1].second, xs[i].first));

    ans.push_back(ii(xs.front().first, xs.back().second));

    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    if (M >= N)
    {
        cout << "NO\n";
        return 0;
    }

    while (M--)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

class UFDS
{
private:
    std::vector<int> size, ps;
    int count;

public:
    UFDS(int N) : size(N + 1, 1), ps(N + 1), count(N)
    {
        std::iota(ps.begin(), ps.end(), 0);
    }

    int find_set(int x) const
    {
        return x == ps[x] ? x : find_set(ps[x]);
    }

    bool same_set(int x, int y)
    {
        return find_set(x) == find_set(y);
    }

    void union_set(int x, int y)
    {
        if (same_set(x, y))
            return;

        int p = find_set(x);
        int q = find_set(y);

        if (size[p] < size[q])
            std::swap(p, q);

        ps[q] = p;
        size[p] += size[q];
        --count;
    }

    int cc() const { return count; };
};

vector<int> adj[MAX];
bitset<MAX> dfs_stack, visited;

bool dfs(int u, int p)
{
    if (visited[u])
        return false;

    visited[u] = true;
    dfs_stack[u] = true;

    for (auto v : adj[u])
    {
        if (v != p and dfs_stack[v])
            return true;

        if (dfs(v, u))
            return true;
    }

    dfs_stack[u] = false;

    return false;
}

bool has_cycle(int N)
{
    for (int u = 1; u <= N; ++u)
        if (not visited[u])
            if (dfs(u, u))
                return true;

    return false;
}

pair<string, vector<ii>> solve(int N, int M)
{
    int d2 = 0, autoloop = 0;

    UFDS ufds(N);

    for (int u = 1; u <= N; ++u)
    {
        if (adj[u].size() == 2ul)
            d2++;

        // Cada vértice deve ter, no máximo, dois vizinhos
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        for (auto v : adj[u])
        {
            ufds.union_set(u, v);
            autoloop += (u == v ? 1 : 0);
        }
    }

    // Se for connectado e grau = 2 todos, ok
    if (ufds.cc() == 1 and d2 == N)
        return { "YES", {} };

    // Se tiver mais de N arestas ou tiver um ciclo, não é possível
    if (M > N or has_cycle(N) or autoloop)
        return { "NO", {} };

    vector<ii> ans;

    for (int u = 1; u <= N; ++u)
    {
        for (int v = u + 1; v <= N; ++v)
        {
            if (adj[u].size() == 2ul)
                break;

            if (adj[v].size() < 2ul and ufds.same_set(u, v) == false)
            {
                ufds.union_set(u, v);
                adj[u].push_back(v);
                adj[v].push_back(u);
                ans.push_back(ii(u, v));
            }
        }
    }

    vector<int> rs;

    for (int u = 1; u <= N; ++u)
        if (adj[u].size() == 1ul)
            rs.push_back(u);

    ans.push_back(ii(rs.front(), rs.back()));

//    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    set<ii> es;

    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;

        int a = min(u, v), b = max(u, v);

        if (es.count(ii(a, b)))
            continue;

        adj[u].push_back(v);
        adj[v].push_back(u);

        es.insert(ii(a, b));
    }

    M = (int) es.size();

    auto [ans, vs] = solve(N, M);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

class UFDS
{
private:
    std::vector<int> size, ps;
    int count;

public:
    UFDS(int N) : size(N + 1, 1), ps(N + 1), count(N)
    {
        std::iota(ps.begin(), ps.end(), 0);
    }

    int find_set(int x) const
    {
        return x == ps[x] ? x : find_set(ps[x]);
    }

    bool same_set(int x, int y)
    {
        return find_set(x) == find_set(y);
    }

    void union_set(int x, int y)
    {
        if (same_set(x, y))
            return;

        int p = find_set(x);
        int q = find_set(y);

        if (size[p] < size[q])
            std::swap(p, q);

        ps[q] = p;
        size[p] += size[q];
        --count;
    }

    int cc() const { return count; };
};

vector<int> adj[MAX];
bitset<MAX> dfs_stack, visited;

bool dfs(int u, int p)
{
    if (visited[u])
        return false;

    visited[u] = true;
    dfs_stack[u] = true;

    for (auto v : adj[u])
    {
        if (v != p and dfs_stack[v])
            return true;

        if (dfs(v, u))
            return true;
    }

    dfs_stack[u] = false;

    return false;
}

bool has_cycle(int N)
{
    for (int u = 1; u <= N; ++u)
        if (not visited[u])
            if (dfs(u, u))
                return true;

    return false;
}

pair<string, vector<ii>> solve(int N, int M)
{
    int d2 = 0, autoloop = 0;

    UFDS ufds(N);

    for (int u = 1; u <= N; ++u)
    {
        if (adj[u].size() == 2ul)
            d2++;

        // Cada vértice deve ter, no máximo, dois vizinhos
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        for (auto v : adj[u])
        {
            ufds.union_set(u, v);
            autoloop += (u == v ? 1 : 0);
        }
    }

    // Se for connectado e grau = 2 todos, ok
    if (ufds.cc() == 1 and d2 == N)
        return { "YES", {} };

    // Se tiver mais de N arestas ou tiver um ciclo, não é possível
    if (M > N or has_cycle(N) or autoloop)
        return { "NO", {} };

    vector<ii> ans;

    for (int u = 1; u <= N; ++u)
    {
        for (int v = u + 1; v <= N; ++v)
        {
            if (adj[u].size() == 2ul)
                break;

            if (adj[v].size() < 2ul and ufds.same_set(u, v) == false)
            {
                ufds.union_set(u, v);
                adj[u].push_back(v);
                adj[v].push_back(u);
                ans.push_back(ii(u, v));
            }
        }
    }

    vector<int> rs;

    for (int u = 1; u <= N; ++u)
        if (adj[u].size() == 1ul)
            rs.push_back(u);

    ans.push_back(ii(rs.front(), rs.back()));

//    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N, M);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

vector<int> adj[MAX];
bitset<MAX> found;

void dfs(int u, int p, int& w)
{
    if (found[u])
        return;

    found[u] = true;

    if (adj[u].size() == 1ul and u != p)
    {
        w = u;
        return;
    }

    for (auto v : adj[u])
        dfs(v, p, w);
}

pair<string, vector<ii>> solve(int N)
{
    vector<ii> xs;
    vector<int> ys;

    for (int u = 1; u <= N; ++u)
    {
LOG(u, ' '); LOG(adj[u].size(), endl);
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        if (adj[u].empty())
            xs.push_back(ii(u, u));
        else if (adj[u].size() == 1ul)
            ys.push_back(u);
    }

    LOGV(ys, endl);

    for (auto u : ys)
    {
        if (found[u])
            continue;

        int v;
        dfs(u, u, v);

        xs.push_back(ii(u, v));
    }

    sort(xs.begin(), xs.end());

    LOGV(xs, endl);

    vector<ii> ans;

    for (size_t i = 1; i < xs.size(); ++i)
        ans.push_back(ii(xs[i - 1].second, xs[i].first));

    if (not xs.empty())
        ans.push_back(ii(xs.front().first, xs.back().second));

    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    if (M > N)
    {
        cout << "NO\n";
        return 0;
    }

    while (M--)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

class UFDS
{
private:
    std::vector<int> size, ps;
    int count;

public:
    UFDS(int N) : size(N + 1, 1), ps(N + 1), count(N)
    {
        std::iota(ps.begin(), ps.end(), 0);
    }

    int find_set(int x) const
    {
        return x == ps[x] ? x : find_set(ps[x]);
    }

    bool same_set(int x, int y)
    {
        return find_set(x) == find_set(y);
    }

    void union_set(int x, int y)
    {
        if (same_set(x, y))
            return;

        int p = find_set(x);
        int q = find_set(y);

        if (size[p] < size[q])
            std::swap(p, q);

        ps[q] = p;
        size[p] += size[q];
        --count;
    }

    int cc() const { return count; };
};

vector<int> adj[MAX];
bitset<MAX> dfs_stack, visited;

bool dfs(int u, int p)
{
    if (visited[u])
        return false;

    visited[u] = true;
    dfs_stack[u] = true;

    for (auto v : adj[u])
    {
        if (v != p and dfs_stack[v])
            return true;

        if (dfs(v, u))
            return true;
    }

    dfs_stack[u] = false;

    return false;
}

bool has_cycle(int N)
{
    for (int u = 1; u <= N; ++u)
        if (not visited[u])
            if (dfs(u, u))
                return true;

    return false;
}

pair<string, vector<ii>> solve(int N, int M)
{
    int d2 = 0, autoloop = 0;

    UFDS ufds(N);

    for (int u = 1; u <= N; ++u)
    {
        if (adj[u].size() == 2ul)
            d2++;

        // Cada vértice deve ter, no máximo, dois vizinhos
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        for (auto v : adj[u])
        {
            ufds.union_set(u, v);
            autoloop += (u == v ? 1 : 0);
        }
    }

    // Se for connectado e grau = 2 todos, ok
    if (ufds.cc() == 1 and d2 == N)
        return { "YES", {} };

    // Se tiver mais de N arestas ou tiver um ciclo, não é possível
    if (M > N or has_cycle(N) or autoloop)
        return { "NO", {} };

    vector<ii> ans;

    for (int u = 1; u <= N; ++u)
    {
        for (int v = u + 1; v <= N; ++v)
        {
            if (adj[u].size() == 2ul)
                break;

            if (adj[v].size() < 2ul and ufds.same_set(u, v) == false)
            {
                ufds.union_set(u, v);
                adj[u].push_back(v);
                adj[v].push_back(u);
                ans.push_back(ii(u, v));
            }
        }
    }

    vector<int> rs;

    for (int u = 1; u <= N; ++u)
        if (adj[u].size() == 1ul)
            rs.push_back(u);

    LOGV(rs, endl);

    if (rs.empty())
        return { "NO", {} };

    ans.push_back(ii(rs.front(), rs.back()));

//    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    set<ii> es;

    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N, M);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

class UFDS
{
private:
    std::vector<int> size, ps;
    int count;

public:
    UFDS(int N) : size(N + 1, 1), ps(N + 1), count(N)
    {
        std::iota(ps.begin(), ps.end(), 0);
    }

    int find_set(int x) const
    {
        return x == ps[x] ? x : find_set(ps[x]);
    }

    bool same_set(int x, int y)
    {
        return find_set(x) == find_set(y);
    }

    void union_set(int x, int y)
    {
        if (same_set(x, y))
            return;

        int p = find_set(x);
        int q = find_set(y);

        if (size[p] < size[q])
            std::swap(p, q);

        ps[q] = p;
        size[p] += size[q];
        --count;
    }

    int cc() const { return count; };
};

vector<int> adj[MAX];
bitset<MAX> dfs_stack, visited;

bool dfs(int u, int p)
{
    if (visited[u])
        return false;

    visited[u] = true;
    dfs_stack[u] = true;

    for (auto v : adj[u])
    {
        if (v != p and dfs_stack[v])
            return true;

        if (dfs(v, u))
            return true;
    }

    dfs_stack[u] = false;

    return false;
}

bool has_cycle(int N)
{
    for (int u = 1; u <= N; ++u)
        if (not visited[u])
            if (dfs(u, u))
                return true;

    return false;
}

pair<string, vector<ii>> solve(int N, int M)
{
    int d2 = 0, autoloop = 0;

    UFDS ufds(N);

    for (int u = 1; u <= N; ++u)
    {
        if (adj[u].size() == 2ul)
            d2++;

        // Cada vértice deve ter, no máximo, dois vizinhos
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        for (auto v : adj[u])
        {
            ufds.union_set(u, v);
            autoloop += (u == v ? 1 : 0);
        }
    }

    // Se for connectado e grau = 2 todos, ok
    if (ufds.cc() == 1 and d2 == N)
        return { "YES", {} };

    // Se tiver mais de N arestas ou tiver um ciclo, não é possível
    if (M > N or has_cycle(N) or autoloop)
        return { "NO", {} };

    vector<ii> ans;

    for (int u = 1; u <= N; ++u)
    {
        for (int v = u + 1; v <= N; ++v)
        {
            if (adj[u].size() == 2ul)
                break;

            if (adj[v].size() < 2ul and ufds.same_set(u, v) == false)
            {
                ufds.union_set(u, v);
                adj[u].push_back(v);
                adj[v].push_back(u);
                ans.push_back(ii(u, v));
            }
        }
    }

    vector<int> rs;

    for (int u = 1; u <= N; ++u)
        if (adj[u].size() == 1ul)
            rs.push_back(u);

    LOGV(rs, endl);

    if (rs.empty())
    {
        if (N == 1)
            return { "YES", { { 1, 1 } } };
        else
            return { "NO", {} };
    }

    ans.push_back(ii(rs.front(), rs.back()));

//    sort(ans.begin(), ans.end());

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    set<ii> es;

    for (int i = 0; i < M; ++i)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N, M);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef DEBUG
#define LOG(var, sep) (cerr << #var << " = " << (var) << (sep))

#define LOGM(msg) (cerr << (msg))

#define LOGV(vec, sep) {                                        \
    cerr << #vec << " =";                                       \
    for (const auto& v : (vec)) cerr << " " << v;               \
    cerr << (sep); }

#define LOGA(arr, N, sep) {                                     \
        cerr << #arr << " =";                                   \
        for (int i = 0; i < N; ++i) cerr << " " << (arr)[i];    \
        cerr << (sep); }

#define LOGA2(arr, N, M, sep) {                                 \
        cerr << #arr << " =\n";                                 \
        for (int i = 0; i < N; ++i) {                           \
            for (int j = 0; j < M; ++j)                         \
                cerr << (arr)[i][j] << " ";                     \
            cerr << endl;                                       \
        } cerr << (sep); }
#else
#define LOG(var, sep)
#define LOGM(msg)
#define LOGV(vec, sep)
#define LOGA(arr, N, sep)
#define LOGA2(arr, N, M, sep)
#endif

using namespace std;
using ii = pair<int, int>;

ostream& operator<<(ostream& os, const ii& p)
{
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

const int MAX { 50 };

vector<int> adj[MAX];
bitset<MAX> found;

void dfs(int u, int p, int& w)
{
    if (found[u])
        return;

    found[u] = true;

    if (adj[u].size() == 1ul and u != p)
    {
        w = u;
        return;
    }

    for (auto v : adj[u])
        dfs(v, p, w);
}

pair<string, vector<ii>> solve(int N)
{
    vector<ii> xs;
    vector<int> ys;

    for (int u = 1; u <= N; ++u)
    {
LOG(u, ' '); LOG(adj[u].size(), endl);
        if (adj[u].size() > 2ul)
            return { "NO", {} };

        if (adj[u].empty())
            xs.push_back(ii(u, u));
        else if (adj[u].size() == 1ul)
            ys.push_back(u);
    }

    LOGV(ys, endl);

    for (auto u : ys)
    {
        if (found[u])
            continue;

        int v;
        dfs(u, u, v);

        xs.push_back(ii(u, v));
    }

    sort(xs.begin(), xs.end());

    LOGV(xs, endl);

    vector<ii> ans;

    for (size_t i = 1; i < xs.size(); ++i)
        ans.push_back(ii(xs[i - 1].second, xs[i].first));

    if (not xs.empty())
        ans.push_back(ii(xs.front().first, xs.back().second));

    sort(ans.begin(), ans.end());

    for (auto [u, v] : ans)
    {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    found.reset();

    int p;
    dfs(1, N + 1, p);

    if ((int) found.count() < N)
        return { "NO", { } };

    return { "YES", ans };
}

int main()
{
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    if (M > N)
    {
        cout << "NO\n";
        return 0;
    }

    while (M--)
    {
        int u, v;
        cin >> u >> v;

        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    auto [ans, vs] = solve(N);

    cout << ans << '\n';

    if (ans == "YES")
    {
        auto K = vs.size();
        cout << vs.size() << '\n';

        for (size_t i = 0; i < K; ++i)
            cout << vs[i].first << ' ' << vs[i].second << '\n';
    }

    return 0;
}


#include <iostream>

const int N = 50, M = 2500;

int n, m;
int degree[N], root[N], count;

int find_root(int x) {
	return root[x] == x ? x : root[x] = find_root(root[x]);
}

int belong(int x, int y) {
	return count <= 1 ? 0 : find_root(x) == find_root(y);
}

int main() {
	scanf_s("%d%d", &n, &m);
	if (m > n) return printf_s("NO"), 0;
	if (n == 1 && m == 0) return printf_s("YES\n1\n1 1"), 0;
	for (int i = 1; i <= n; ++i) root[i] = i;
	count = n;
	for (int i = 1, a, b; i <= m; ++i) {
		scanf_s("%d%d", &a, &b);
		if (degree[a] == 2 || degree[b] == 2) return printf_s("NO"), 0;
		if (belong(a, b)) return printf_s("NO"), 0;
		++degree[a], ++degree[b];
		root[find_root(a)] = find_root(b);
		--count;
	}
	printf_s("YES\n%d\n", n - m);
	for (int i = 1; i <= n; ++i)
		while (degree[i] < 2)
			for (int j = i + 1; j <= n; ++j)
				if (!belong(i, j) && degree[j] < 2) {
					printf_s("%d %d\n", i, j),
						++degree[i], ++degree[j];
					root[find_root(i)] = find_root(j);
					--count;
					break;
				}

	return 0;
}


#include <iostream>

const int N = 50 + 7, M = 2500 + 7;

int n, m;
int degree[N], root[N], count;

int find_root(int x) {
	return root[x] == x ? x : root[x] = find_root(root[x]);
}

int belong(int x, int y) {
	return count <= 1 ? 0 : find_root(x) == find_root(y);
}

int main() {
	scanf_s("%d%d", &n, &m);
	if (m > n) return printf_s("NO"), 0;
	if (n == 1 && m == 0) return printf_s("YES\n1\n1 1"), 0;
	for (int i = 1; i <= n; ++i) root[i] = i;
	count = n;
	for (int i = 1, a, b; i <= m; ++i) {
		scanf_s("%d%d", &a, &b);
		if (degree[a] == 2 || degree[b] == 2) return printf_s("NO"), 0;
		if (belong(a, b)) return printf_s("NO"), 0;
		++degree[a], ++degree[b];
		root[find_root(a)] = find_root(b);
		--count;
	}
	printf_s("YES\n%d\n", n - m);
	for (int i = 1; i <= n; ++i)
		while (degree[i] < 2)
			for (int j = i + 1; j <= n; ++j)
				if (!belong(i, j) && degree[j] < 2) {
					printf_s("%d %d\n", i, j),
						++degree[i], ++degree[j];
					root[find_root(i)] = find_root(j);
					--count;
					break;
				}

	system("pause");
	return 0;
}