#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 4e5 + 12;
constexpr int MOD = 998244353;
constexpr int INF = (1 << 31);
constexpr int LOG = 3e3;
int n, m, vis[MAXN], dp[MAXN], mark[MAXN], h[MAXN], ch[MAXN], st[MAXN],
    ed[MAXN], tme, mark2[MAXN], par[MAXN], mark3[MAXN], mark4[MAXN];
vector<int> G[MAXN], ans, H[MAXN], out, Child[MAXN];
void dfs1(int u) {
  vis[u] = 1;
  st[u] = tme;
  tme++;
  ch[u] = h[u];
  for (auto v : G[u]) {
    if (!vis[v]) {
      h[v] = h[u] + 1;
      par[v] = u;
      dfs1(v);
    }
  }
  for (auto v : G[u]) {
    if (v != par[u]) {
      ch[u] = min(ch[u], ch[v]);
    }
  }
  if (ch[u] == h[u]) {
    mark2[u] = 1;
  }
  ed[u] = tme;
  tme++;
}
void dfs(int u) {
  vis[u] = 1;
  for (auto v : G[u]) {
    if (!vis[v]) {
      dfs(v);
    }
  }
  bool ok = true;
  for (auto v : G[u]) {
    if (v != par[u]) {
      if (mark[v]) {
        mark[u] = 1;
        ok = false;
      }
    }
  }
  if (ok && mark2[u]) {
    ans.push_back(u);
    mark[u] = 1;
  }
}
void Create_dp(int u) {
  for (auto v : Child[u]) {
    Create_dp(v);
  }
  for (auto v : Child[u]) {
    if (mark3[v] || dp[v] != 0) {
      dp[u] += dp[v] + mark3[v];
    }
  }
}
int find_down_vertex(int u) {
  if (mark3[u]) {
    return u;
  }
  int mx = 0, p = 0;
  for (auto v : Child[u]) {
    if (dp[v] > mx && !mark4[v]) {
      mx = dp[v];
      p = v;
    }
    if (mx == 0 && mark3[v] && !mark4[v]) {
      p = v;
    }
  }
  if (p == 0) {
    return 1;
  }
  return find_down_vertex(p);
}
void Update(int u) {
  dp[u]--;
  mark2[u] = 0;
  mark3[u] = 0;
  if (u == 1) {
    return;
  }
  Update(par[u]);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  if (m == 1 && n == 2) {
    return cout << -1, 0;
  }
  dfs1(1);
  memset(vis, 0, sizeof vis);
  dfs(1);
  for (auto u : ans) {
    mark3[u] = 1;
  }
  for (int i = 2; i <= n; i++) {
    Child[par[i]].push_back(i);
  }
  Create_dp(1);
  for (int i = 1; i <= n; i++) {
    if (mark2[i]) {
      H[h[i]].push_back(i);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (auto v : H[i]) {
      if (!mark2[v]) {
        continue;
      }
      mark4[v] = 1;
      int u = find_down_vertex(v), k;
      bool ok = false;
      if (dp[par[v]] == 1) {
        if (dp[1] != 1) {
          ok = true;
        } else {
          if (par[u] == 1) {
            u = Child[u][0];
          }
          k = 1;
          Update(u);
        }
      } else {
        Update(u);
        k = find_down_vertex(par[v]);
        if (k != 1) {
          Update(k);
        }
      }
      if (ok) {
        Update(u);
        k = find_down_vertex(1);
        if (k != 1) {
          Update(k);
        }
      }
      out.push_back(k);
      out.push_back(u);
      mark4[v] = 0;
    }
  }
  cout << (int)out.size() / 2 << "\n";
  for (int i = 0; i < out.size(); i++) {
    cout << out[i] << " ";
    i++;
    cout << out[i] << "\n";
  }
  return 0;
}
