#include <bits/stdc++.h>
using namespace std;
struct CHT {
  set<pair<pair<long long, long long>, long long> > S;
  set<pair<long long, pair<long long, long long> > > I;
  long long INF = 2e18;
  inline void Add(pair<long long, long long> X) {
    long long t = -INF;
    auto it = S.lower_bound({X, -INF});
    while ((int)S.size() > 0) {
      if (it == S.begin()) {
        t = -INF;
        break;
      }
      it--;
      long long r = Intersection(it->first, X);
      if (r <= it->second)
        I.erase({it->second, it->first}), it = S.erase(it);
      else {
        t = r;
        break;
      }
    }
    it = S.lower_bound({X, -INF});
    while ((int)S.size() > 0) {
      if (it == S.end()) break;
      long long r = Intersection(X, it->first);
      pair<long long, long long> Y = it->first;
      I.erase({it->second, it->first});
      it = S.erase(it);
      if (r <= t) {
        r = -INF;
        if (it != S.begin()) it--, r = Intersection(it->first, Y);
        S.insert({Y, r});
        I.insert({r, Y});
        return;
      }
      if (it != S.end() && it->second <= r) continue;
      S.insert({Y, r});
      I.insert({r, Y});
      break;
    }
    S.insert({X, t});
    I.insert({t, X});
  }
  inline long long GetMax(long long X) {
    auto it = I.upper_bound({X, {INF, INF}});
    it--;
    return (X * it->second.first + it->second.second);
  }
  inline long long Intersection(pair<long long, long long> X,
                                pair<long long, long long> Y) {
    if (X.first == Y.first && X.second <= Y.second) return (-INF);
    if (X.first == Y.first) return (INF);
    return ((X.second - Y.second) / (Y.first - X.first)) +
           ((X.second - Y.second) % (Y.first - X.first) > 0);
  }
};
const int N = 500005;
int n, SZ[N];
long long Mn = LLONG_MAX, dp[N];
vector<int> Adj[N];
inline bool CMP(int i, int j) { return (SZ[i] < SZ[j]); }
void DFS(int v, int p) {
  SZ[v] = 1;
  for (int i = 0; i < Adj[v].size(); i++)
    if (Adj[v][i] == p) Adj[v].erase(Adj[v].begin() + i);
  if (!Adj[v].size()) return void(dp[v] = 0);
  for (int u : Adj[v]) DFS(u, v), SZ[v] += SZ[u];
  sort(Adj[v].begin(), Adj[v].end(), CMP);
  CHT C;
  for (int u : Adj[v]) {
    long long b = dp[u] - (long long)SZ[u] * (n + n - 1 - SZ[u]);
    if (C.S.size())
      Mn = min(Mn, (long long)n * (n - 1) + b - C.GetMax(2LL * SZ[u]));
    C.Add({-SZ[u], -b});
    dp[v] =
        min(dp[v], dp[u] + (long long)(SZ[v] - SZ[u]) * (SZ[v] - SZ[u] - 1));
    Mn = min(Mn, dp[u] + (long long)(n - SZ[u]) * (n - SZ[u] - 1));
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int v, u;
    scanf("%d%d", &v, &u);
    Adj[v].push_back(u);
    Adj[u].push_back(v);
  }
  if (n == 2) return !printf("2\n");
  int root = 1;
  for (int i = 1; i <= n; i++)
    if (Adj[i].size() > 1) root = i;
  memset(dp, 63, sizeof(dp));
  DFS(root, 0);
  return !printf("%lld\n", (long long)n * (n - 1) - Mn / 2);
}
