#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500005;
const long long INF = 1E18;
struct Edge {
  int to, next;
} edge[MAXN << 1];
int head[MAXN], sz[MAXN], n, tot;
void addedge(int u, int v) {
  edge[++tot] = (Edge){v, head[u]};
  head[u] = tot;
}
long long g[MAXN], ans = INF;
inline long long sqr(int x) { return (long long)x * (x - 1) / 2; }
void prep(int u, int fa) {
  sz[u] = 1;
  for (int i = head[u]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == fa) continue;
    prep(v, u);
    sz[u] += sz[v];
  }
}
int que[MAXN];
vector<int> son;
double slope(int a, int b) {
  return (double)(g[a] + sqr(sz[a]) - g[b] - sqr(sz[b])) / (sz[a] - sz[b]);
}
void dfs(int u, int fa) {
  g[u] = INF;
  int cs = 0;
  for (int i = head[u]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == fa) continue;
    dfs(v, u);
    g[u] = min(g[u], g[v] + sqr(sz[u] - sz[v]));
    ans = min(ans, g[v] + sqr(n - sz[v]));
    ++cs;
  }
  if (cs == 0) {
    g[u] = 0;
    return;
  }
  son.reserve(cs);
  son.clear();
  for (int i = head[u]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == fa) continue;
    son.push_back(v);
  }
  sort(son.begin(), son.end(), [&](int x, int y) { return sz[x] > sz[y]; });
  int he = 1, ta = 0;
  for (int i : son) {
    while (he < ta && slope(que[he], que[he + 1]) >= n - sz[i] - 0.5) ++he;
    if (he <= ta)
      ans = min(ans, g[i] + g[que[he]] + sqr(n - sz[que[he]] - sz[i]));
    while (he < ta && slope(que[ta - 1], que[ta]) <= slope(que[ta], i)) --ta;
    que[++ta] = i;
  }
}
int main() {
  scanf("%d", &n);
  ans = (long long)n * (n - 1);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    addedge(u, v);
    addedge(v, u);
  }
  prep(1, 0);
  dfs(1, 0);
  printf("%lld\n", (long long)n * (n - 1) - ans);
  return 0;
}
