#include <bits/stdc++.h>
class Solution {
  struct Center {
    int midPoint, diam;
    bool operator<(Center other) const { return diam < other.diam; }
  };
  std::vector<std::pair<int, int>> edgeAdded;
  std::vector<std::vector<int>> g;
  int n;
  std::vector<Center> getCenterArray(std::vector<std::vector<int>> g) {
    std::vector<Center> centerArray;
    std::vector<int> compo, parent(n);
    std::vector<int> dep(n, 0);
    std::vector<int> isVisited(n, false);
    std::function<void(int, int)> deepestDfs = [&](int u, int p) {
      isVisited[u] = true;
      compo.push_back(u);
      parent[u] = p;
      for (int v : g[u]) {
        if (v == p) continue;
        dep[v] = dep[u] + 1;
        deepestDfs(v, u);
      }
    };
    std::function<std::vector<int>(int)> getRoute = [&](int u) {
      std::vector<int> ret;
      while (parent[u] != u) ret.push_back(u), u = parent[u];
      ret.push_back(u);
      return ret;
    };
    std::function<int(const std::vector<int> &)> getDeepestNode =
        [&](const std::vector<int> &compo) {
          return *std::max_element(
              compo.begin(), compo.end(),
              [&](int u, int v) { return dep[u] < dep[v]; });
        };
    for (int i = 0; i < n; ++i) {
      if (isVisited[i]) continue;
      compo.clear();
      deepestDfs(i, i);
      int v = getDeepestNode(compo);
      compo.clear();
      deepestDfs(v, v);
      v = getDeepestNode(compo);
      auto diameter = getRoute(v);
      assert(diameter.size() > 0);
      centerArray.push_back(
          {int(diameter[diameter.size() / 2]), int(diameter.size() - 1)});
    }
    return centerArray;
  }
  Center merge(Center a, Center b) {
    int aEcc = (a.diam + 1) / 2, bEcc = (b.diam + 1) / 2;
    Center ret;
    edgeAdded.emplace_back(a.midPoint, b.midPoint);
    ret.diam = std::max({a.diam, b.diam, aEcc + bEcc + 1});
    if (a.diam == ret.diam)
      ret.midPoint = a.midPoint;
    else if (b.diam == ret.diam)
      ret.midPoint = b.midPoint;
    else {
      if (aEcc < bEcc)
        ret.midPoint = b.midPoint;
      else
        ret.midPoint = a.midPoint;
    }
    return ret;
  }
  int greedySolution(std::vector<Center> d) {
    reverse(d.begin(), d.end());
    sort(d.begin(), d.end());
    while (d.size() > 1) {
      Center a = d.back();
      d.pop_back();
      Center b = d.back();
      d.pop_back();
      d.push_back(merge(a, b));
    }
    return d.back().diam;
  }

 public:
  void run(std::istream &in, std::ostream &out) {
    in >> n;
    int m;
    in >> m;
    g.resize(n);
    for (int i = 0, u, v; i < m; ++i) {
      in >> u >> v;
      --u, --v;
      g[u].push_back(v), g[v].push_back(u);
    }
    out << greedySolution(getCenterArray(g)) << '\n';
    while (edgeAdded.size()) {
      auto edge = edgeAdded.back();
      out << edge.first + 1 << ' ' << edge.second + 1 << '\n';
      edgeAdded.pop_back();
    }
  }
};
int main() {
  std::ios_base::sync_with_stdio(false);
  Solution().run(std::cin, std::cout);
  return 0;
}
