#include <bits/stdc++.h>
using namespace std;
int n;
vector<vector<int> > tree;
vector<pair<int, int> > edges;
vector<int> node_size;
vector<vector<bool> > vis;
vector<vector<long long> > dp;
int root;
void compute_size(int node, int from) {
  node_size[node] = 1;
  for (int nei : tree[node]) {
    if (nei != from) {
      compute_size(nei, node);
      node_size[node] += node_size[nei];
    }
  }
}
long long get_size(int node, int from) {
  if (node_size[from] > node_size[node]) {
    return node_size[node];
  } else {
    return n - node_size[from];
  }
}
long long max_mex(int u, int v, int u_from, int v_from) {
  if (vis[u][v]) {
    return dp[u][v];
  } else {
    vis[u][v] = true;
    long long &ans = dp[u][v];
    ans = 0;
    for (int nxt : tree[u]) {
      if (nxt != u_from) {
        ans = max(ans, get_size(nxt, u) * get_size(v, v_from) +
                           max_mex(nxt, v, u, v_from));
      }
    }
    for (int nxt : tree[v]) {
      if (nxt != v_from) {
        ans = max(ans, (get_size(nxt, v) * get_size(u, u_from) +
                        max_mex(u, nxt, u_from, v)));
      }
    }
    return ans;
  }
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int T = 1;
  while (T--) {
    cin >> n;
    tree = vector<vector<int> >(n + 1);
    node_size = vector<int>(n + 1, 0);
    vis = vector<vector<bool> >(n + 1, vector<bool>(n + 1, false));
    dp = vector<vector<long long> >(n + 1, vector<long long>(n + 1, 0));
    edges = vector<pair<int, int> >();
    for (int i = 1; i < n; i++) {
      int u, v;
      cin >> u >> v;
      edges.push_back({u, v});
      tree[u].push_back(v);
      tree[v].push_back(u);
    }
    root = 1;
    compute_size(root, 0);
    long long ans = 0;
    for (auto edge : edges) {
      ans = max(ans,
                get_size(edge.first, edge.second) *
                        get_size(edge.second, edge.first) +
                    max_mex(edge.first, edge.second, edge.second, edge.first));
    }
    cout << ans << '\n';
  }
}
