//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            assert(!(center[i] == 99 && leaf[i].front() == 57));
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist, vector<int> &max_path) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist, max_path);
        }
    }
     max_path[v] = dist[v];
    for (int to : g[v]) {
        max_path[v] = max(max_path[v], max_path[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv;
    for (int to : g[v]) {
        vv.push_back(max_path[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        if (start_v == 206) {
            cout << "vv.size() = 1" << endl;
        }
        return vv[0] - 1;
    }
    if (start_v == 206) {
        cout << "vv.size() = " << vv.size() << endl;
        for (int j : vv) {
            cout << j << ' ';
        }
        cout << endl;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    vector<int> max_path(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i], max_path));
        if (D == 32) {
            cout << "main_tree = " << main_tree << endl;
            cout << "D = " << 32 << ", i = " << i << endl;
            return 0;
        }
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            assert(k == 2);
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    for (int to : g[v]) {
        dist[v] = max(dist[v], dist[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i]));
    }
    if (D == 33) {
        cout << "D = " << 33 << endl;
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist, vector<int> &max_path) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist, max_path);
        }
    }
     max_path[v] = dist[v];
    for (int to : g[v]) {
        max_path[v] = max(max_path[v], max_path[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv;
    for (int to : g[v]) {
        vv.push_back(max_path[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        if (start_v == 206) {
            cout << "vv.size() = 1" << endl;
        }
        return vv[0] - 1;
    }
    if (start_v == 206) {
        cout << "vv.size() = " << vv.size() << endl;
        for (int j : vv) {
            cout << j << ' ';
        }
        cout << endl;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    vector<int> max_path(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i], max_path));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, max_path[center[i]] - 1 + max_path[center[main_tree]]);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist, vector<int> &max_path) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist, max_path);
        }
    }
     max_path[v] = dist[v];
    for (int to : g[v]) {
        max_path[v] = max(max_path[v], max_path[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv;
    for (int to : g[v]) {
        vv.push_back(max_path[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    vector<int> max_path(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i], max_path));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, max_path[center[i]] - 1 + max_path[center[main_tree]]);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    for (int to : g[v]) {
        dist[v] = max(dist[v], dist[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i]));
        if (D == 32) {
            cout << "main_tree = " << main_tree << endl;
            cout << "D = " << 32 << ", i = " << i << endl;
            return 0;
        }
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            assert(!(center[i] == 20 && leaf[i].front() == 21));
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    if (v != start[v]) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    if (n == 100 && m == 98) {
        cout << r[57] << ' ' << r[99] << endl;
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    if (n == 100 && m == 98) {
        for (int i = 0; i < n; i++) {
            dist[1][i] = 0;
        }
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            assert(!(center[i] == 99 && leaf[i].front() == 57));
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
//    if (R.size() > 2) {
//        D = max(D, R[1] + R[2] + 2);
//    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        while (!leaf[i].empty()) {
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    r[to] = r[center[i]] + 1;
                    leaf[i].push(to);
                }
            }
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<int> dist(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
        }
    }
    for (int i = 0; i < col; i++) {
        while (!leaf[i].empty()) {
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to] && p[to] <= 1) {
                    r[to] = r[center[i]] + 1;
                    leaf[i].push(to);
                }
            }
            deleted[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<int> dist(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    for (int to : g[v]) {
        dist[v] = max(dist[v], dist[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
        }
    }
    for (int i = 0; i < col; i++) {
        while (!leaf[i].empty()) {
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                if (!deleted[to]) {
                    r[to] = r[center[i]] + 1;
                    leaf[i].push(to);
                }
            }
            deleted[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<int> dist(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist, vector<int> &max_path) {
    if (v == start_v) {
        dist[v] = 1;
    }
    max_path[v] = dist[v];
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist, max_path);
        }
    }
    for (int to : g[v]) {
        max_path[v] = max(max_path[v], max_path[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(max_path[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    vector<int> max_path(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i], max_path));
        if (D == 32) {
            cout << "main_tree = " << main_tree << endl;
            cout << "D = " << 32 << ", i = " << i << endl;
            return 0;
        }
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    if (start_v == 57) {
        for (int i : dist) {
            cout << i << ' ';
        }
        cout << endl;
    }
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    if (n == 100 && m == 98) {
        cout << r[57] << ' ' << r[99] << endl;
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < n; i++) {
        dist[1][i] = 0;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist, vector<int> &max_path) {
    if (v == start_v) {
        dist[v] = 1;
    }
    max_path[v] = dist[v];
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist, max_path);
        }
    }
    for (int to : g[v]) {
        max_path[v] = max(max_path[v], max_path[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv;
    for (int to : g[v]) {
        vv.push_back(max_path[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        if (start_v == 206) {
            cout << "vv.size() = 1" << endl;
        }
        return vv[0] - 1;
    }
    if (start_v == 206) {
        cout << "vv.size() = " << vv.size() << endl;
        for (int j : vv) {
            cout << j << ' ';
        }
        cout << endl;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    vector<int> max_path(n, 0);
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i], max_path));
        if (D == 32) {
            cout << "main_tree = " << main_tree << endl;
            cout << "D = " << 32 << ", i = " << i << endl;
            return 0;
        }
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    if (start_v == 57) {
        for (int i : dist) {
            cout << i << ' ';
        }
        cout << endl;
    }
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    if (n == 100 && m == 98) {
        cout << r[57] << ' ' << r[99] << endl;
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    if (n == 100 && m == 98) {
        for (int i = 0; i < n; i++) {
            dist[1][i] = 0;
        }
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
    }
    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    for (int to : g[v]) {
        dist[v] = max(dist[v], dist[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i]));
    }
    if (D == 32) {
        cout << "D = " << 32 << endl;
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int dfs2 (int start_v, int v, vector<vector<int>> &g, vector<int> &dist) {
    if (v == start_v) {
        dist[v] = 1;
    }
    for (int to : g[v]) {
        if (!dist[to]) {
            dist[to] = dist[v] + 1;
            dfs2(start_v, to, g, dist);
        }
    }
    for (int to : g[v]) {
        dist[v] = max(dist[v], dist[to]);
    }
    if (v != start_v) {
        return 0;
    }
    vector<int> vv; for (int to : g[v]) {
        vv.push_back(dist[to]);
    }
    sort(vv.begin(), vv.end());
    reverse(vv.begin(), vv.end());
    if (vv.size() == 0) {
        return 0;
    }
    if (vv.size() == 1) {
        return vv[0] - 1;
    }
    return vv[0] + vv[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
//    for (int i : center) {
//        cout << i << ' ';
//    }
//    cout << endl;
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, dfs2(center[i], center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to]) {
                    r[to] = max(r[to], r[center[i]] + 1);
                }
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    if (n == 100 && m == 98) {
        cout << r[57] << ' ' << r[99] << endl;
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    if (n == 100 && m == 98 && bfs(99, g, dist[1]) == 21) {
        cout << "--" << endl;
    }
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
        if (D == 22) {
            cout << i;
            return 0;
        }
    }
//    assert(D != 22);
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}


//Author: Tanya Cheremkhina

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    #define cin fin
    #define cout fout
#endif //DEBUG

void dfs1 (int v, vector<vector<int>> &g, vector<int> &used, int col) {
    used[v] = col;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs1(to, g, used, col);
        }
    }
}

int bfs (int start_v, vector<vector<int>> &g, vector<int> &dist) {
    queue<int> que;
    que.push(start_v);
    dist[start_v] = 1;
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (dist[to] == 0) {
                que.push(to);
                dist[to] = dist[v] + 1;
            }
        }
    }
    sort(dist.begin(), dist.end());
    reverse(dist.begin(), dist.end());
    return dist[0] + dist[1] - 2;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector<vector<int>> g(n);
    vector<int> p(n, 0), used(n, 0);;
    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);
        p[v]++;
        p[u]++;
    }
    int col = 1;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs1(i, g, used, col);
            col++;
        }
    }
    for (int &i : used) {
        i--;
    }
    col--;
    vector<int> center(col, -1), r(n, 0);
    vector<queue<int>> leaf(col);
    vector<int> deleted(n, 0);
    for (int i = 0; i < n; i++) {
        if (p[i] <= 1) {
            leaf[used[i]].push(i);
            deleted[i] = 1;
        }
    }
    for (int i = 0; i < col; i++) {
        int k = 0;
        while (!leaf[i].empty()) {
            k++;
            center[i] = leaf[i].front();
            leaf[i].pop();
            for (int to : g[center[i]]) {
                p[to]--;
                if (!deleted[to] && p[to] <= 1) {
                    deleted[to] = 1;
                    r[to] = r[center[i]] + 1;
                    leaf[i].push(to);
                }
            }
        }
        if (r[center[i]] == 0 && k > 1) {
            r[center[i]] = 1;
        }
    }
    int main_tree = 0;
    for (int i = 0; i < col; i++) {
        if (r[center[i]] > r[center[main_tree]]) {
            main_tree = i;
        }
    }
    vector<vector<int>> dist(col, vector<int> (n, 0));
    int D = 0;
    for (int i = 0; i < col; i++) {
        D = max(D, bfs(center[i], g, dist[i]));
    }
    vector<pair<int, int>> ans;
    for (int i = 0; i < col; i++) {
        if (i != main_tree) {
            D = max(D, r[center[i]] + r[center[main_tree]] + 1);
            ans.emplace_back(center[i] + 1, center[main_tree] + 1);
        }
    }
    vector<int> R(col);
    for (int i = 0; i < col; i++) {
        R[i] = r[center[i]];
    }
    sort(R.begin(), R.end());
    reverse(R.begin(), R.end());
    if (R.size() > 2) {
        D = max(D, R[1] + R[2] + 2);
    }
    cout << D << '\n';
    for (auto i : ans) {
        cout << i.first << ' ' << i.second << '\n';
    }
    return 0;
}