// Generated By Gemini 3.1 Pro for test #include #include #include #include using namespace std; int main() { // 入出力の高速化 ios_base::sync_with_stdio(false); cin.tie(NULL); int N; if (!(cin >> N)) return 0; vector> adj(N + 1); for (int i = 0; i < N - 1; ++i) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } // BFSで開始点からの距離を計算し、最も遠い頂点を返すラムダ式 auto bfs = [&](int start, vector& dist) { dist.assign(N + 1, -1); queue q; q.push(start); dist[start] = 0; int farthest_node = start; while (!q.empty()) { int u = q.front(); q.pop(); for (int v : adj[u]) { if (dist[v] == -1) { dist[v] = dist[u] + 1; q.push(v); farthest_node = v; } } } return farthest_node; }; vector dist_from_any, dist_X, dist_Y; // 1. 直径の端点 X, Y を求める int X = bfs(1, dist_from_any); int Y = bfs(X, dist_X); bfs(Y, dist_Y); int diameter = dist_X[Y]; // 木の直径 // 2. 通常の木DP (Xを根とする) vector height(N + 1, 0); vector parent(N + 1, 0); // ボトムアップで部分木の深さを計算 auto dfs = [&](auto& self, int u, int p) -> void { parent[u] = p; for (int v : adj[u]) { if (v == p) continue; self(self, v, u); height[u] = max(height[u], height[v] + 1); } }; dfs(dfs, X, 0); long long ans = 1; // 3. 各頂点を中心としたウニ木の最大サイズを計算 for (int i = 1; i <= N; ++i) { vector L; // 各方向への最長パス長 for (int v : adj[i]) { if (v == parent[i]) { // 親方向への辺 // 頂点 i が直径 X-Y のパス上にあるか判定 if (dist_X[i] + dist_Y[i] == diameter) { // パス上にある場合、Y は部分木側にあるため、親方向の最遠点は X のみ L.push_back(dist_X[i]); } else { // パス上にない場合、親方向の最遠点は X か Y の遠い方 L.push_back(max(dist_X[i], dist_Y[i])); } } else { // 子方向への辺(通常の木DPの結果) L.push_back(height[v] + 1); } } // 降順にソートして貪欲に計算 sort(L.rbegin(), L.rend()); for (int k_idx = 0; k_idx < L.size(); ++k_idx) { long long branches = k_idx + 1; long long depth = L[k_idx]; ans = max(ans, branches * depth + 1); } } cout << ans << "\n"; return 0; }