#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10, P = 5e5 + 10;
const long long inf = 1e18 + 42;
struct point {
  long long m, c;
  point() : m(0), c(inf) {}
  point(long long _m, long long _c) : m(_m), c(_c) {}
};
point line[4 * P];
struct li_chao_tree {
  void add_line(point add, int i = 1, long long l = 0, long long r = P) {
    long long m = (l + r) / 2;
    bool lef = (eval(add, l) < eval(line[i], l));
    bool mid = (eval(add, m) < eval(line[i], m));
    if (mid) {
      swap(add, line[i]);
    }
    if (l == r - 1) {
      return;
    } else if (lef != mid) {
      add_line(add, 2 * i, l, m);
    } else {
      add_line(add, 2 * i + 1, m, r);
    }
  }
  long long query(long long x, int i = 1, long long l = 0, long long r = P) {
    long long ans = eval(line[i], x), m = (l + r) / 2;
    if (l == r - 1) {
      return ans;
    } else if (x < m) {
      return min(ans, query(x, 2 * i, l, m));
    } else {
      return min(ans, query(x, 2 * i + 1, m, r));
    }
  }
  long long eval(point p, long long x) { return p.m * x + p.c; }
  void clear(int i = 1, long long l = 0, long long r = P) {
    long long m = (l + r) / 2;
    if (line[i].m == 0 and line[i].c == inf) {
      return;
    } else if (l == r - 1) {
      line[i] = {0, inf};
    } else {
      line[i] = {0, inf};
      clear(2 * i, l, m);
      clear(2 * i + 1, m, r);
    }
  }
} lct;
vector<int> g[N];
long long ans = inf;
int sz[N], deg[N];
long long cost[N];
void dfs1(int u, int p);
long long dfs2(int u, int p, int n);
long long c2(long long x);
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n;
  cin >> n;
  if (n == 2) {
    cout << 2 << endl;
    return 0;
  }
  for (int i = 2; i <= n; ++i) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
    ++deg[u];
    ++deg[v];
  }
  int root = 1;
  while (deg[root] == 1) {
    ++root;
  }
  dfs1(root, 0);
  dfs2(root, 0, n);
  cout << 2 * c2(n) - ans << endl;
}
void dfs1(int u, int p) {
  sz[u] = 1;
  for (auto &v : g[u]) {
    if (v == p) {
      continue;
    } else {
      dfs1(v, u);
      sz[u] += sz[v];
    }
  }
}
long long dfs2(int u, int p, int n) {
  vector<pair<long long, long long> > check;
  cost[u] = c2(sz[u]);
  if (p != 0) {
    cost[u] += cost[p] - c2(sz[p]) + c2(sz[p] - sz[u]);
  }
  long long ret = cost[u];
  for (auto &v : g[u]) {
    if (v == p) {
      continue;
    } else {
      long long cand = dfs2(v, u, n);
      ret = min(ret, cand);
      check.push_back({sz[v], cand});
    }
  }
  if (check.size() > 1) {
    for (auto &i : check) {
      i.second -= (cost[u] - c2(sz[u]) + c2(sz[u] - i.first));
      i.second += (i.first * i.first + i.first - 2 * n * i.first) / 2;
    }
    lct.add_line({check[0].first, check[0].second});
    int k = check.size();
    for (int i = 1; i < k; ++i) {
      long long temp = lct.query(check[i].first) + check[i].second + c2(n);
      ans = min(ans, temp);
      lct.add_line({check[i].first, check[i].second});
    }
    lct.clear();
  }
  return ret;
}
long long c2(long long x) { return (x * (x - 1)) / 2; }
