//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;
    }
    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 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] = 0;
    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;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	while(!q.empty()){
		ret = q.back();
		q.pop();
		seen[ret] = true;
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 +2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen, vector<int>& dist){
	int ret;
	queue<int> q;
	q.push(st);
	dist[st] = 0;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		seen[ret] = true;
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			dist[z] = dist[ret] + 1;
			q.push(z);
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	len++;
	if(nd == sght) return stck[stck.size()/2];
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<int> dist1(n+1);
	vector<int> dist2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1, dist1);
		int e2 = BFS(e1, seen2, dist2);
		int len = -1;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 +2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;
vector<pair<int,int>> wght;
vector<bool> seen;

int DFS(int nd, int& maxL, vector<int>& cc){
	cc.push_back(nd);
	seen[nd] = true;
	int ans = nd;
	for(auto it = adj[nd].begin(); it != adj[nd].end(); it++){
		if(seen[*it]) continue;
		int deep_nd = DFS(*it, maxL, cc);
		int len = wght[*it].first + 1;
		maxL = max(maxL, len);
		if(len > wght[nd].first){
			swap(len, wght[nd].first);
			ans = deep_nd;
		}
		if(len > wght[nd].second) wght[nd].second = len;
	}
	/*dbg(nd)
	dbg(ans)
	dbg(maxL)
	*/return ans;
}

int find_median(int nd, int ft, int len, vector<int>& stck){
	stck.push_back(nd);
	/*dbg(nd)
	dbg(len)
	dbg(stck.size())
	*/if(int(stck.size()) == len+1) return stck[len/2];
	for(auto it = adj[nd].begin(); it != adj[nd].end(); it++){
		if(*it == ft) continue;
		int ret = find_median(*it, nd, len, stck);
		if(ret != 0) return ret;
	}
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	wght = vector<pair<int,int>>(n+1);
	seen = vector<bool>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<vector<int>> ccs;
	vector<pair<int,int>> mm;
	for(int i=1; i<=n; i++){
		if(seen[i]) continue;
		vector<int> cc;
		int maxL = 0;
		int endPt = DFS(i, maxL, cc);
		vector<int> stck;
		int mdn = find_median(endPt, -1, maxL, stck);
		//dbg(endPt)
		//dbg(mdn)
		ccs.push_back(cc);
		mm.push_back(make_pair(maxL, mdn));
	}
	sort(mm.begin(), mm.end(), greater<pair<int,int>>());

	//for(auto z : mm) cout << z.first << " " << z.second <<endl;

	if(mm.size() == 1){
		cout << mm[0].first << endl;
		return 0;
	}
	cout << (mm[0].first+1)/2 + (mm[1].first+1)/2 + 1<< endl;
	auto im = mm.begin();
	im++;
	while(im != mm.end()){
		cout << mm[0].second << " " << im++->second << endl;
	}

	//for(auto x : ccs) {for(auto z : x) cout << z <<" "; cout << endl;}
	//for(auto x : adj) {for(auto z : x) cout << z <<" "; cout << endl;}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	deque<int> q;
	q.push_back(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.front();
		q.pop_back();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push_back(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		if(n == 100) cout << i << endl;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	deque<int> q;
	q.push_back(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.front();
		q.pop_front();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push_back(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	/*dbg(nd)
	dbg(len)
	*/stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		//dbg(z)
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	//n = 10;
	adj = vector<vector<int>>(n+1);
	/*for(int i=2; i<=10; i++){
		adj[1].push_back(i);
		adj[i].push_back(1);
	}*/
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		cout << i << endl;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		//dbg(e1) dbg(e2)
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	deque<int> q;
	q.push_back(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.front();
		q.pop_front();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push_back(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	sort(lgMd.begin(), lgMd.end(), greater<pair<int,int>>());
	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	/*dbg(nd)
	dbg(len)
	*/stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		//dbg(z)
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	//n = 10;
	adj = vector<vector<int>>(n+1);
	/*for(int i=2; i<=10; i++){
		adj[1].push_back(i);
		adj[i].push_back(1);
	}*/
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		if(n == 100) cout << i << endl;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		//dbg(e1) dbg(e2)
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 +2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;
vector<pair<int,int>> wght;
vector<bool> seen;

int DFS(int nd, int& maxL, vector<int>& cc){
	cc.push_back(nd);
	seen[nd] = true;
	int ans = nd;
	for(auto it = adj[nd].begin(); it != adj[nd].end(); it++){
		if(seen[*it]) continue;
		int deep_nd = DFS(*it, maxL, cc);
		int len = wght[*it].first + 1;
		maxL = max(maxL, len);
		if(len > wght[nd].first){
			swap(len, wght[nd].first);
			ans = deep_nd;
		}
		if(len > wght[nd].second) wght[nd].second = len;
	}
	/*dbg(nd)
	dbg(ans)
	dbg(maxL)
	*/return ans;
}

int find_median(int nd, int ft, int len, vector<int>& stck){
	stck.push_back(nd);
	/*dbg(nd)
	dbg(len)
	dbg(stck.size())
	*/if(int(stck.size()) == len+1) return stck[len/2];
	for(auto it = adj[nd].begin(); it != adj[nd].end(); it++){
		if(*it == ft) continue;
		int ret = find_median(*it, nd, len, stck);
		if(ret != 0) return ret;
	}
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	wght = vector<pair<int,int>>(n+1);
	seen = vector<bool>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<vector<int>> ccs;
	vector<pair<int,int>> mm;
	for(int i=1; i<=n; i++){
		if(seen[i]) continue;
		vector<int> cc;
		int maxL = 0;
		int endPt = DFS(i, maxL, cc);
		vector<int> stck;
		int mdn = find_median(endPt, -1, maxL, stck);
		//dbg(endPt)
		//dbg(mdn)
		ccs.push_back(cc);
		mm.push_back(make_pair(maxL, mdn));
	}
	sort(mm.begin(), mm.end(), greater<pair<int,int>>());

	//for(auto z : mm) cout << z.first << " " << z.second <<endl;

	int diam;
	if(mm.size() == 1) diam = mm[0].first;
	if(mm.size() == 2) diam = (mm[0].first+1)/2 + (mm[1].first+1)/2 + 1;
	if(mm.size() > 2){
		diam = max((mm[0].first+1)/2, (mm[2].first+1)/2 + 1) + (mm[1].first+1)/2 + 1;
	}
	cout << diam << endl;
	auto im = mm.begin();
	im++;
	while(im != mm.end()){
		cout << mm[0].second << " " << im++->second << endl;
	}

	//for(auto x : ccs) {for(auto z : x) cout << z <<" "; cout << endl;}
	//for(auto x : adj) {for(auto z : x) cout << z <<" "; cout << endl;}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	while(!q.empty()){
		ret = q.back();
		q.pop();
		seen[ret] = true;
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	if(nd == sght) return stck[stck.size()/2];
	stck.push_back(nd);
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 +2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	deque<int> q;
	q.push_back(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.front();
		q.pop_front();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push_back(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	adj = vector<vector<int>>(n+1);
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		if(n == 100) cout << i << endl;
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}

	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
			seen[z] = true;
		}
	}
	return ret;
}

void DFS2(int nd, vector<bool>& seen){
	seen[nd] = true;
	for(auto z : adj[nd]){
		if(seen[nd]) continue;
		DFS2(z, seen);
	}
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	/*dbg(nd)
	dbg(len)
	*/stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		//dbg(z)
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	//n = 10;
	adj = vector<vector<int>>(n+1);
	/*for(int i=2; i<=10; i++){
		adj[1].push_back(i);
		adj[i].push_back(1);
	}*/
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		if(seen1[i]) continue;
		if(n == 100) cout << i << endl;
		int e1 = BFS(i, seen1);
		DFS2(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		//dbg(e1) dbg(e2)
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include<bits/stdc++.h>
#define dbg(x) cerr << #x  << ": " << x << endl;
#define endl '\n'
using namespace std;
typedef long long ll;

vector<vector<int>> adj;

int BFS(int st, vector<bool>& seen){
	int ret = st;
	queue<int> q;
	q.push(st);
	seen[st] = true;
	while(!q.empty()){
		ret = q.back();
		q.pop();
		for(auto z : adj[ret]){
			if(seen[z]) continue;
			q.push(z);
			seen[z] = true;
		}
	}
	return ret;
}

int DFS(int nd, int ft, int sght, int& len, vector<int>& stck){
	/*dbg(nd)
	dbg(len)
	*/stck.push_back(nd);
	if(nd == sght) return stck[stck.size()/2];
	len++;
	for(auto z : adj[nd]){
		if(z == ft) continue;
		//dbg(z)
		int ans = DFS(z, nd, sght, len, stck);
		if(ans) return ans;
	}
	len--;
	stck.pop_back();
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	//n = 10;
	adj = vector<vector<int>>(n+1);
	/*for(int i=2; i<=10; i++){
		adj[1].push_back(i);
		adj[i].push_back(1);
	}*/
	while(m--){
		int a, b;
		cin >> a >> b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<bool> seen1(n+1);
	vector<bool> seen2(n+1);
	vector<pair<int,int>> lgMd;
	for(int i = 1; i <= n; i++){
		//dbg(i)
		if(seen1[i]) continue;
		dbg(i)
		int e1 = BFS(i, seen1);
		int e2 = BFS(e1, seen2);
		int len = 0;
		vector<int> stck;
		//dbg(e1) dbg(e2)
		int md = DFS(e1, -1, e2, len, stck);
		lgMd.push_back(make_pair(len, md));
	}
	//for(auto z : lgMd) cout << z.first << " " << z.second << endl;

	int diam =lgMd[0].first;
	if(lgMd.size() > 1) diam = max(diam, (lgMd[0].first+1)/2 + (lgMd[1].first+1)/2 + 1);
	if(lgMd.size() > 2) diam = max(diam, (lgMd[1].first+1)/2 + (lgMd[2].first+1)/2 + 2);
	cout <<  diam << endl;
	auto it = lgMd.begin();
	it++;
	while(it != lgMd.end()){
		cout << lgMd[0].second << " " << it++->second << endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
vector <pair <int, int> > adj[100001];
vector <pair<long long, long long> > dia;
vector <long long> half;
vector <int> cen;
int n, m, l, a, b, t, endpt, c, tc;
long long diameter, h, maxd;
bool v[100001];
void dfs(int x, int p, long long dist){
    v[x] = true;
    if (dist > diameter){
        diameter = dist;
        endpt = x;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if (adj[x][i].first != p)
            dfs(adj[x][i].first, x, dist + adj[x][i].second);
}
bool dfs_half(int x, int p, long long dist){
    if (dist == diameter){
        if (diameter - dist >= diameter / 2 && dist <= diameter / 2){
            h = min(h, diameter - dist);
            if (h == diameter - dist)
                    tc = x;
        }
        if (dist >= diameter / 2 && diameter - dist <= diameter / 2){
            h = min(h, dist);
            if (h ==  dist)
                    tc = x;
        }

        return true;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if(adj[x][i].first != p && dfs_half(adj[x][i].first, x, dist + adj[x][i].second)){
            if (diameter - dist >= diameter / 2 && dist <= diameter / 2){
                h = min(h, diameter - dist);
                if (h == diameter - dist)
                    tc = x;
            }
            if (dist >= diameter / 2 && diameter - dist <= diameter / 2){
                h = min(h, dist);
                if (h == dist)
                    tc = x;
            }
            return true;
        }
    return false;
}
int main(){
    //scanf("%d%d%d", &n, &m, &l);
    scanf("%d%d", &n, &m);
    l = 1;
    for (int i = 0; i < m; i++){
        //scanf("%d%d%d", &a, &b, &t);
        scanf("%d%d", &a, &b);
        t = 1;
        adj[a].push_back({b, t});
        adj[b].push_back({a, t});
    }
    maxd = -1;
    memset(v, 0 , sizeof(v));
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            h = (long long) 1e18;
            endpt = -10;
            dfs(i, -1, 0);
            diameter = -1;
            dfs(endpt, -1, 0);
            dfs_half(endpt, -1, 0);
            dia.push_back({diameter, h});
            //printf("%d %d %lld %lld\n", i, endpt, diameter, h);
            //
            if (diameter > maxd){
                maxd = diameter;
                c = tc;
            }
            cen.push_back(tc);
            //
        }
    sort(dia.begin(), dia.end(), greater<pair<long long, long long> >());
    half.push_back(dia[0].second);
    half.push_back(dia[0].first - dia[0].second);
    for (int i = 1; i < (int)dia.size(); i++)
        half.push_back(dia[i].second + l);
    sort(half.begin(), half.end(), greater<long long>());
    printf("%lld\n", half[0] + half[1]);
    ///*
    for (int i = 0; i < (int)cen.size(); i++)
        if (cen[i] != c)
            printf("%d %d\n", c, cen[i]);
    //*/
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}

void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia){
                final_dia = diameter;
                final_center = center;
            }
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    //if (final_dia == )
    printf("%d\n", final_dia);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", final_center, ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter, min_dia;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia){
                final_dia = diameter;
                final_center = center;
            }
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    else if (final_dia == 2 && ans.size() > 1 && min_dia > 0){
        final_dia++;
    }
    //if (final_dia == )
    printf("%d\n", final_dia);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", final_center, ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        diameter = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
vector <pair <int, int> > adj[100001];
vector <pair<long long, long long> > dia;
vector <long long> half;
int n, m, l, a, b, t, endpt;
long long diameter, h;
bool v[100001];
void dfs(int x, int p, long long dist){
    v[x] = true;
    if (dist > diameter){
        diameter = dist;
        endpt = x;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if (adj[x][i].first != p)
            dfs(adj[x][i].first, x, dist + adj[x][i].second);
}
bool dfs_half(int x, int p, long long dist){
    if (dist == diameter){
        if (diameter - dist >= diameter / 2 && dist <= diameter / 2)
            h = min(h, diameter - dist);
        if (dist >= diameter / 2 && diameter - dist <= diameter / 2)
            h = min(h, dist);
        return true;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if(adj[x][i].first != p && dfs_half(adj[x][i].first, x, dist + adj[x][i].second)){
            if (diameter - dist >= diameter / 2 && dist <= diameter / 2)
                h = min(h, diameter - dist);
            if (dist >= diameter / 2 && diameter - dist <= diameter / 2)
                h = min(h, dist);
            return true;
        }
    return false;
}
int main(){
    //scanf("%d%d%d", &n, &m, &l);
    scanf("%d%d%d", &n, &m);
    l = 1;
    for (int i = 0; i < m; i++){
        //scanf("%d%d%d", &a, &b, &t);
        scanf("%d%d", &a, &b);
        t = 1;
        adj[a].push_back({b, t});
        adj[b].push_back({a, t});
    }
    memset(v, 0 , sizeof(v));
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            h = (long long) 1e18;
            endpt = -10;
            dfs(i, -1, 0);
            diameter = -1;
            dfs(endpt, -1, 0);
            dfs_half(endpt, -1, 0);
            dia.push_back({diameter, h});
            printf("%d %d %lld %lld\n", i, endpt, diameter, h);
        }
    sort(dia.begin(), dia.end(), greater<pair<long long, long long> >());
    half.push_back(dia[0].second);
    half.push_back(dia[0].first - dia[0].second);
    for (int i = 1; i < (int)dia.size(); i++)
        half.push_back(dia[i].second + l);
    sort(half.begin(), half.end(), greater<long long>());
    printf("%lld\n", half[0] + half[1]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, maxdia3, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
bool dfs_diameter(int x,int p, int depth){ //center must be along path diameter!!!!! not random node with depth diamter/2!!!!
    if (depth == diameter){
        if (depth == diameter / 2)
            center = x;
        return true;
    }
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p && dfs_diameter(adj[x][i], x, depth + 1)){
            if (depth == diameter / 2)
                center = x;
            return true;
        }
    return false;
    //printf("%d %d %d!!\n", x, depth, diameter);

}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = maxdia2 = maxdia3 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, -1, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia3 = maxdia2;
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia3 = maxdia2;
                maxdia2 = diameter;
            }
            else if (diameter >= maxdia3)
                maxdia3 = diameter;

        }
    if (n == 1 && m == 0){
        printf("0\n");
        return 0;
    }
    int v = max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1);
    if ((int)ans.size() > 2)
        v = max(v, (maxdia2 + 1) / 2 + (maxdia3 + 1) / 2 + 2);
    printf("%d\n", v);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
bool dfs_diameter(int x,int p, int depth){ //center must be along path diameter!!!!! not random node with depth diamter/2!!!!
    if (depth == diameter){
        if (depth == diameter / 2)
            center = x;
        return true;
    }
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p && dfs_diameter(adj[x][i], x, depth + 1)){
            if (depth == diameter / 2)
                center = x;
            return true;
        }
    return false;
    //printf("%d %d %d!!\n", x, depth, diameter);

}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, -1, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter, min_dia;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia || (diameter + 1) / 2 + (final_dia + 1) / 2 + 1 > final_dia){
                final_dia = max(diameter, (diameter + 1) / 2 + (final_dia + 1) / 2 + 1);
                final_center = center;
            }
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    //else if (final_dia == 2 && ans.size() > 1 && min_dia > 0)
    //    final_dia++;
    //if (final_dia == )
    printf("%d\n", final_dia);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", final_center, ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            dfs_endpt(t_endpt, -1, 0);
            diameter = t;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
bool dfs_diameter(int x,int depth){ //center must be along path diameter!!!!! not random node with depth diamter/2!!!!
    v[x] = true;
    if (depth == diameter){
        if (depth == diameter / 2)
            center = x;
        return true;
    }
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]] && dfs_diameter(adj[x][i], depth + 1)){
            if (depth == diameter / 2)
                center = x;
            return true;
        }
    return false;
    //printf("%d %d %d!!\n", x, depth, diameter);

}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter, min_dia;
vector <pair<int, int> > ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia || (diameter + 1) / 2 + (final_dia + 1) / 2 + 1 > final_dia){
                final_dia = max(diameter, (diameter + 1) / 2 + (final_dia + 1) / 2 + 1);
                ans.push_back({center, final_center});
                final_center = center;
            }
            else ans.push_back({center, final_center});
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    printf("%d\n", final_dia);
    for (int i = 1; i <(int) ans.size(); i++)
            printf("%d %d\n", ans[i].first, ans[i].second);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter, min_dia;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia){
                final_dia = diameter;
                final_center = center;
            }
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    //if (final_dia == )
    printf("%d\n", final_dia);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", final_center, ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, endpt, diameter, maxdia, maxdia2, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == diameter / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = 0;
    maxdia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            t = -1;
            dfs_endpt(t_endpt, -1, 0);
            diameter = t;
            dfs_diameter(endpt, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia2 = diameter;
            }
        }
    if (m == 0 && n > 2)
        maxdia ++;
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1));
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, maxdia3, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
bool dfs_diameter(int x,int p, int depth){ //center must be along path diameter!!!!! not random node with depth diamter/2!!!!
    if (depth == diameter){
        if (depth == diameter / 2)
            center = x;
        return true;
    }
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p && dfs_diameter(adj[x][i], x, depth + 1)){
            if (depth == diameter / 2)
                center = x;
            return true;
        }
    return false;
    //printf("%d %d %d!!\n", x, depth, diameter);

}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = maxdia2 = maxdia3 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, -1, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia3 = maxdia2;
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia3 = maxdia2;
                maxdia2 = diameter;
            }
            else if (diameter >= maxdia3)
                maxdia3 = diameter;

        }
    printf("%d\n", max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1), (maxdia2 + 1) / 2 + (maxdia3 + 1) / 2 + 2);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, diameter, min_dia;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            //printf("%d %d %d %d\n", endpt, i, center, diameter);
            if (diameter > final_dia){
                final_dia = diameter;
                final_center = center;
            }
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    else if (final_dia == 2 && ans.size() > 1 && min_dia > 0){
        final_dia++;
    }
    //if (final_dia == )
    printf("%d\n", final_dia);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", final_center, ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, t, center, final_dia, endpt, final_center, final_dia2, diameter, min_dia;
vector <int> ans;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  t){
        t = depth;
        endpt = x;
    }
}
void dfs_diameter(int x,int depth){
    v[x] = true;
    diameter = max(depth, diameter);
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (!v[adj[x][i]])
            dfs_diameter(adj[x][i], depth + 1);
    //printf("%d %d %d!!\n", x, depth, diameter);
    if (depth == (diameter + 1) / 2)
        center = x;
}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    min_dia = n;
    final_dia = 0;
    final_dia2 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            t = -1;
            dfs_endpt(i, -1, 0);
            diameter = -1;
            dfs_diameter(endpt, 0);
            ans.push_back(center);
            if (diameter > final_dia){
                final_dia2 = final_dia;
                final_dia = diameter;
                final_center = center;
            }
            else if (diameter >= final_dia2)
                final_dia2 = diameter;
            min_dia = min(min_dia, diameter);
        }
    if (m == 0){
        final_center = 1;
        if (n == 1)
            final_dia = 0;
        else if (n == 2)
            final_dia = 1;
        else final_dia = 2;
    }
    printf("%d\n", max(final_dia, (final_dia + 1) / 2 + (final_dia2 + 1) / 2 + 1));
    for (int i = 1; i <(int) ans.size(); i++)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
vector <pair <int, int> > adj[100001];
vector <pair<long long, long long> > dia;
vector <long long> half;
int n, m, l, a, b, t, endpt;
long long diameter, h;
bool v[100001];
void dfs(int x, int p, long long dist){
    v[x] = true;
    if (dist > diameter){
        diameter = dist;
        endpt = x;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if (adj[x][i].first != p)
            dfs(adj[x][i].first, x, dist + adj[x][i].second);
}
bool dfs_half(int x, int p, long long dist){
    if (dist == diameter){
        if (diameter - dist >= diameter / 2 && dist <= diameter / 2)
            h = min(h, diameter - dist);
        if (dist >= diameter / 2 && diameter - dist <= diameter / 2)
            h = min(h, dist);
        return true;
    }
    for (int i = 0; i < (int)adj[x].size(); i++)
        if(adj[x][i].first != p && dfs_half(adj[x][i].first, x, dist + adj[x][i].second)){
            if (diameter - dist >= diameter / 2 && dist <= diameter / 2)
                h = min(h, diameter - dist);
            if (dist >= diameter / 2 && diameter - dist <= diameter / 2)
                h = min(h, dist);
            return true;
        }
    return false;
}
int main(){
    //scanf("%d%d%d", &n, &m, &l);
    scanf("%d%d%d", &n, &m);
    l = 1;
    for (int i = 0; i < m; i++){
        //scanf("%d%d%d", &a, &b, &t);
        scanf("%d%d", &a, &b);
        t = 1;
        adj[a].push_back({b, t});
        adj[b].push_back({a, t});
    }
    memset(v, 0 , sizeof(v));
    for (int i = 0; i < n; i++)
        if (!v[i]){
            diameter = -1;
            h = (long long) 1e18;
            endpt = -10;
            dfs(i, -1, 0);
            diameter = -1;
            dfs(endpt, -1, 0);
            dfs_half(endpt, -1, 0);
            dia.push_back({diameter, h});
            printf("%d %d %lld %lld\n", i, endpt, diameter, h);
        }
    sort(dia.begin(), dia.end(), greater<pair<long long, long long> >());
    half.push_back(dia[0].second);
    half.push_back(dia[0].first - dia[0].second);
    for (int i = 1; i < (int)dia.size(); i++)
        half.push_back(dia[i].second + l);
    sort(half.begin(), half.end(), greater<long long>());
    printf("%lld\n", half[0] + half[1]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, center, endpt, diameter, maxdia, maxdia2, maxdia3, final_center;
vector <int> ans, possible_d;
vector <int> adj[1001];
bool v[1001];
void dfs_endpt(int x, int p, int depth){
    //printf("%d %d!!!\n", x, depth);
    v[x] = true;
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p)
            dfs_endpt(adj[x][i], x, depth + 1);
    if (depth >  diameter){
        diameter = depth;
        endpt = x;
    }
}
bool dfs_diameter(int x,int p, int depth){ //center must be along path diameter!!!!! not random node with depth diamter/2!!!!
    if (depth == diameter){
        if (depth == diameter / 2)
            center = x;
        return true;
    }
    for (int i = 0; i < (int) adj[x].size(); i++)
        if (adj[x][i] != p && dfs_diameter(adj[x][i], x, depth + 1)){
            if (depth == diameter / 2)
                center = x;
            return true;
        }
    return false;
    //printf("%d %d %d!!\n", x, depth, diameter);

}
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    memset(v, 0, sizeof(v));
    maxdia = maxdia2 = maxdia3 = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i]){
            diameter = -1;
            dfs_endpt(i, -1, 0);
            int t_endpt = endpt;
            diameter = -1;
            dfs_endpt(t_endpt, -1, 0);
            dfs_diameter(t_endpt, -1, 0);
            //printf("%d %d %d %d\n", i, endpt, diameter, center);
            ans.push_back(center);
            if (diameter >= maxdia){
                maxdia3 = maxdia2;
                maxdia2 = maxdia;
                maxdia = diameter;
                final_center = center;
            }
            else if (diameter >= maxdia2){
                maxdia3 = maxdia2;
                maxdia2 = diameter;
            }
            else if (diameter >= maxdia3)
                maxdia3 = diameter;

        }
    int v = max(maxdia, (maxdia + 1) / 2 + (maxdia2 + 1) / 2 + 1);
    if ((int)ans.size() > 2)
        v = max(v, (maxdia2 + 1) / 2 + (maxdia3 + 1) / 2 + 2);
    printf("%d\n", v);
    for (int i = 0; i <(int) ans.size(); i++)
        if (ans[i] != final_center)
            printf("%d %d\n", ans[i], final_center);
    return 0;
}
//original algorithm: diameter not yet fixed and center has been fixed..


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    dfs(far, -1, 2, 0, d2);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        int res, x, y;
        res = (v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2;
        x = v[1].se; y = v[2].se;
        if ((v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 < res) {
            res = (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2;
            x = v[0].se, y = v[1].se;
        }
        if ((v[0].fi + 1) / 2 + 1 + (v[2].fi + 1) / 2 < res) {
            res = (v[0].fi + 1) / 2 + 1 + (v[2].fi + 1) / 2;
            x = v[0].se, y = v[2].se;
        }
        cout << res << '\n' << x << ' ' << y;
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int id, int d, int dist[]) {
    if (mark[u] == 0) vtx.push_back(u);
    mark[u] = id;

    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }

    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    int tmp;

    dfs(s, 1, 0, d1);
    l = 0; tmp = far;
    dfs(tmp, 2, 0, d2);
    l = 0; tmp = far;
    dfs(tmp, 3, 0, d1);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        cout <<  max((v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2,
                  (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2) << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    //debug(far);
    l = 0;
    dfs(far, -1, 2, 0, d2);
    //debug(far);
    l = 0;
    dfs(far, -1, 3, 0, d1);
    //debug(far);
    //debug(l);
    REP(i, vtx.size()) {
        int u = vtx[i];
        //cerr << u << ' ' << d1[u] << ' ' << d2[u] << '\n';
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            //cerr << "tree: " << l << ' ' << u << '\n';
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        //cerr << i << '\n';
        if (!mark[i]) process(i);
    }
    //cerr << v.size() << '\n';
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        cout <<  min((v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2,
                  (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2) << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    dfs(far, -1, 2, 0, d2);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        int res, x, y;
        res = (v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2;
        if ((v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 < res) {
            res = (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2;
        }
        if ((v[0].fi + 1) / 2 + 1 + (v[2].fi + 1) / 2 < res) {
            res = (v[0].fi + 1) / 2 + 1 + (v[2].fi + 1) / 2;
        }
        cout << res << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int id, int d, int dist[]) {
    if (mark[u] == 0) vtx.push_back(u);
    mark[u] = id;

    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }

    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    int tmp;

    dfs(s, 1, 0, d1);
    l = 0; tmp = far;
    dfs(tmp, 2, 0, d2);
    l = 0; tmp = far;
    dfs(tmp, 3, 0, d1);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << max(v[0].fi, (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2) << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        cout <<  max(v[0].fi, max((v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2,
                  (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2)) << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    //debug(far);
    l = 0;
    dfs(far, -1, 2, 0, d2);
    //debug(far);
    l = 0;
    dfs(far, -1, 3, 0, d1);
    //debug(far);
    //debug(l);
    REP(i, vtx.size()) {
        int u = vtx[i];
        //cerr << u << ' ' << d1[u] << ' ' << d2[u] << '\n';
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            //cerr << "tree: " << l << ' ' << u << '\n';
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        //cerr << i << '\n';
        if (!mark[i]) process(i);
    }
    //cerr << v.size() << '\n';
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        cout <<  max((v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2,
                  (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2) << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], vtx;
vector<ii> v;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    l = 0;
    dfs(far, -1, 2, 0, d2);
    l = 0;
    dfs(far, -1, 1, 0, d1);
    //debug(l);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            v.push_back(mp(l, u));
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<ii>());
    if (v.size() == 1) cout << v[0].fi;
    else if (v.size() == 2) {
        cout << (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2 << '\n';
        cout << v[0].se << ' ' << v[1].se << '\n';
    } else {
        cout <<  max((v[1].fi + 1) / 2 + 2 + (v[2].fi + 1) / 2,
                  (v[0].fi + 1) / 2 + 1 + (v[1].fi + 1) / 2) << '\n';
        FOR(i, 1, v.size() - 1) cout << v[0].se << ' ' << v[i].se << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define REP(i,n) for (int i = 0; i < (n); ++ i)
#define FOR(i,a,b) for (int i = (a); i <= (b); ++ i)
#define FORD(i,b,a) for (int i = (b); i >= (a); -- i)

#define debug(x) cerr << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

#define task ""

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> li;
typedef vector<int> vi;

const int N = 1e3 + 5;

int far, l, n, m;
int mark[N], d1[N], d2[N];
vi adj[N], v, vtx, mid;

void dfs(int u, int par, int id, int d, int dist[]) {
    if (id == 1) vtx.push_back(u);
    dist[u] = d;
    if (d > l) {
        l = d;
        far = u;
    }
    mark[u] = id;
    REP(i, adj[u].size()) {
        int v = adj[u][i];
        if (mark[v] != id) {
            dfs(v, u, id, d + 1, dist);
        }
    }
}

void process(int s) {
    vtx.clear();
    far = s, l = 0;
    dfs(s, -1, 1, 0, d1);
    dfs(far, -1, 2, 0, d2);
    v.push_back(l);
    REP(i, vtx.size()) {
        int u = vtx[i];
        if (d1[u] == l / 2 && d2[u] == (l + 1) / 2) {
            mid.push_back(u);
            break;
        }
    }
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen(task".inp", "r", stdin);
	//freopen(task".out", "w", stdout);
    cin >> n >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    FOR(i, 1, n) {
        if (!mark[i]) process(i);
    }
    sort(all(v), greater<int>());
    if (v.size() == 1) cout << v[0];
    else if (v.size() == 2) {
        cout << (v[0] + 1) / 2 + 1 + (v[1] + 1) / 2 << '\n';
        cout << mid[0] << ' ' << mid[1] << '\n';
    } else {
        int res, x, y;
        res = (v[1] + 1) / 2 + 2 + (v[2] + 1) / 2;
        x = mid[1]; y = mid[2];
        if ((v[0] + 1) / 2 + 1 + (v[1] + 1) / 2 < res) {
            res = (v[0] + 1) / 2 + 1 + (v[1] + 1) / 2;
            x = mid[0], y = mid[1];
        }
        if ((v[0] + 1) / 2 + 1 + (v[2] + 1) / 2 < res) {
            res = (v[0] + 1) / 2 + 1 + (v[2] + 1) / 2;
            x = mid[0], y = mid[2];
        }
        cout << res << '\n' << x << ' ' << y;
    }
}