//無向グラフの木の直径を求める(重みなしなら辺のcostを1に)
struct edge
{
long long to;
long long cost;
edge(long long t, long long c) : to(t), cost(c) {}
};
pair<long long, long long> dia_dfs(const vector<vector<edge>> &G, long long v, long long par)
{
pair<long long, long long> ret = make_pair(0, v);
for (auto e : G[v])
{
long long nv = e.to;
if (nv == par)
continue;
auto next = dia_dfs(G, nv, v);
next.first += e.cost;
ret = max(ret, next);
}
return ret;
}
long long tree_diameter(const vector<vector<edge>> &G)
{
auto p = dia_dfs(G, 0, -1), q = dia_dfs(G, p.second, -1);
return q.first;
}
//木の直径の端点の組の1つを返す(0-indexed)
pair<long long, long long> tree_end_nodes(const vector<vector<edge>> &G)
{
auto p = dia_dfs(G, 0, -1), q = dia_dfs(G, p.second, -1);
return make_pair(p.second, q.second);
}