#include <bits/stdc++.h>
using namespace std;
const long long inf = ((long long)1) << 60;
struct func {
  long long a, b;
  long long getV(long long x) { return a * x + b; }
  bool operator<(func& o) { return a < o.a; }
  long long getR(func& o) {
    if (a == o.a) return b > o.b ? inf : -inf;
    long long d = b >= o.b ? 0 : o.a - a - 1;
    return (b - o.b - d) / (o.a - a);
  }
};
struct convexhullelement {
  bool q;
  mutable long long r;
  func* f;
  bool operator<(const convexhullelement& o) const {
    if (!q && !o.q) return *f < *o.f;
    return r < o.r;
  }
};
struct convexhull : public multiset<convexhullelement> {
  bool bad(iterator y) {
    auto z = next(y);
    if (y == begin()) {
      if (z == end()) return false;
      return y->f->getR(*z->f) == -inf;
    }
    auto x = prev(y);
    if (z == end()) return x->f->getR(*y->f) == inf;
    return x->f->getR(*y->f) >= y->f->getR(*z->f);
  }
  void update(iterator y) {
    auto z = next(y);
    y->r = z == end() ? inf : y->f->getR(*z->f);
    if (y != begin()) prev(y)->r = prev(y)->f->getR(*y->f);
  }
  void add(func* f) {
    convexhullelement e = {false, 0, f};
    auto y = insert(e);
    if (bad(y)) {
      erase(y);
      return;
    }
    while (next(y) != end() && bad(next(y))) erase(next(y));
    while (y != begin() && bad(prev(y))) erase(prev(y));
    update(y);
  }
  func* query(long long p) {
    convexhullelement e = {true, p, 0};
    auto it = lower_bound(e);
    if (it == end()) return 0;
    return it->f;
  }
  long long getV(long long p) {
    func* f = query(p);
    return f->getV(p);
  }
};
long long n;
vector<int> e[600000];
long long r, s[600000], dp[600000][2];
convexhull c[600000];
void dfs(int i, int p = -1) {
  s[i] = 1;
  for (int j : e[i]) {
    if (j == p) continue;
    dfs(j, i);
    s[i] += s[j];
  }
  dp[i][0] = s[i] * (s[i] - 1) / 2;
  long long b = dp[i][0];
  for (int j : e[i]) {
    if (j == p) continue;
    long long h = (s[i] - s[j]) * (s[i] - s[j] - 1) / 2 + dp[j][0];
    b = min(b, h);
  }
  dp[i][0] = b;
  dp[i][1] = n * (n - 1) / 2;
  for (int j : e[i]) {
    if (j == p) continue;
    dp[i][1] = min(dp[i][1], dp[j][1]);
    dp[i][1] = min(dp[i][1], dp[j][0] + (n - s[j]) * (n - s[j] - 1) / 2);
    func* f = new func();
    f->b = -(dp[j][0] + s[j] * (1 - 2 * n + s[j]) / 2);
    f->a = -s[j];
    func* af = c[i].query(s[j]);
    if (af != 0)
      dp[i][1] = min(dp[i][1], -(f->b + af->getV(s[j])) + n * (n - 1) / 2);
    c[i].add(f);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(10);
  cin >> n;
  int a, b;
  for (int i = 0; i < n - 1; i++) {
    cin >> a >> b;
    a--, b--;
    e[a].push_back(b);
    e[b].push_back(a);
  }
  dfs(0);
  r = n * (n - 1) - dp[0][1];
  cout << r << "\n";
}
