#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> adj;
  vector<vector<int>> g(n, adj);
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  queue<int> q;
  vector<int> vis(n, 0);
  vector<vector<int>> tree(n, adj);
  vector<int> dist(n, 0);
  vector<pair<int, int>> max1(n, {-1, 0});
  vector<pair<int, int>> max2(n, {-1, 0});
  vector<int> fork(n, 0);
  vector<pair<int, int>> locdia;
  for (int i = 0; i < n; i++) {
    if (vis[i]) continue;
    vector<pair<int, int>> dis;
    q.push(i);
    vis[i] = 1;
    dis.push_back({0, i});
    dist[i] = 0;
    while (!q.empty()) {
      int curr = q.front();
      q.pop();
      for (int j = 0; j < g[curr].size(); j++) {
        int vtx = g[curr][j];
        if (!vis[vtx]) {
          vis[vtx] = 1;
          q.push(vtx);
          dist[vtx] = dist[curr] + 1;
          dis.push_back({dist[vtx], vtx});
          tree[curr].push_back(vtx);
        }
      }
    }
    int forkindex = -1;
    int currmax = -1;
    for (int j = dis.size() - 1; j >= 0; j--) {
      int curr = dis[j].second;
      if (!tree[curr].size()) {
        if (currmax == -1) {
          currmax = 0;
          forkindex = curr;
          continue;
        }
      } else if (tree[curr].size() == 1) {
        int ch = tree[curr][0];
        max1[curr].first = ch;
        max1[curr].second = max1[ch].second + 1;
        fork[curr] = max1[curr].second;
      } else {
        for (int k = 0; k < tree[curr].size(); k++) {
          int ch = tree[curr][k];
          if (max1[ch].second + 1 > max2[curr].second) {
            if (max1[ch].second + 1 > max1[curr].second) {
              max2[curr] = max1[curr];
              max1[curr] = {ch, max1[ch].second + 1};
            } else
              max2[curr] = {ch, max1[ch].second + 1};
          }
        }
        fork[curr] = max1[curr].second + max2[curr].second;
      }
      if (fork[curr] > currmax) {
        currmax = fork[curr];
        forkindex = curr;
      }
    }
    int root = forkindex;
    for (int j = 0; j < (max1[forkindex].second + max2[forkindex].second) / 2 -
                            max2[forkindex].second;
         j++)
      root = max1[root].first;
    locdia.push_back({root, currmax});
  }
  vector<pair<int, int>> locdiadup;
  for (int i = 0; i < locdia.size(); i++)
    locdiadup.push_back({locdia[i].second, locdia[i].first});
  sort(locdiadup.begin(), locdiadup.end());
  int newroot = locdiadup[locdia.size() - 1].second;
  int newdia = locdiadup[locdia.size() - 1].first;
  vector<pair<int, int>> newjoins;
  for (int i = locdia.size() - 2; i >= 0; i--) {
    newjoins.push_back({newroot, locdiadup[i].second});
    if (locdiadup[i].first > newdia) newroot = locdiadup[i].second;
    newdia = max(max(newdia, locdiadup[i].first),
                 (int)ceil(((float)(newdia) / 2.0)) +
                     (int)ceil(((float)(locdiadup[i].first) / 2.0)) + 1);
  }
  cout << newdia << endl;
  for (int i = 0; i < newjoins.size(); i++)
    cout << newjoins[i].first + 1 << " " << newjoins[i].second + 1 << endl;
  return 0;
}
