#include <bits/stdc++.h>
using namespace std;
void err(istringstream &iss) {}
template <typename T, typename... Args>
void err(istringstream &iss, const T &varVal, const Args &...args) {
  string varName;
  iss >> varName;
  if (varName.back() == ',') varName.back() = ' ';
  cout << varName << " = " << varVal << "; ", err(iss, args...);
}
int n, m, K, T, Q, cn;
struct info {
  int mx, mxi, mx2, mx2i, mx3, cntChildren;
} nich[205];
int a[205];
list<int> adj[205];
int best_inSubtree[205];
info down_chains[205];
int best_outside[205], longest_up[205];
pair<int, int> best_sub[205][3];
void dfsDown(int u, int p) {
  int mx = -1, mxi = n + 1, mx2 = -1, mx2i = n + 1, mx3 = -1;
  int cntChildren = 0;
  for (int &v : adj[u])
    if (v != p) {
      dfsDown(v, u), cntChildren++;
      int os = down_chains[v].mx + 1;
      if (best_inSubtree[v] > best_sub[u][0].first) {
        best_sub[u][1] = best_sub[u][0];
        best_sub[u][0] = make_pair(best_inSubtree[v], v);
      } else if (best_inSubtree[v] > best_sub[u][1].first) {
        best_sub[u][1] = make_pair(best_inSubtree[v], v);
      }
      if (os > mx)
        mx3 = mx2, mx2 = mx, mx2i = mxi, mx = os, mxi = v;
      else if (os > mx2)
        mx3 = mx2, mx2 = os, mx2i = v;
      else
        mx3 = max(os, mx3);
      best_inSubtree[u] = max(best_inSubtree[u], best_inSubtree[v]);
    }
  mx = max(mx, 0), mx2 = max(mx2, 0), mx3 = max(mx3, 0);
  down_chains[u] = {mx, mxi, mx2, mx2i, mx3, cntChildren};
  best_inSubtree[u] = max(best_inSubtree[u], mx + mx2);
}
void dfsUp(int u, int p) {
  if (u != 1) longest_up[u] = longest_up[p] + 1;
  best_outside[u] = max(best_outside[p], longest_up[p]);
  if (down_chains[p].cntChildren > 1) {
    int sibling =
        (down_chains[p].mxi == u) ? down_chains[p].mx2 : down_chains[p].mx;
    best_outside[u] = max(best_outside[u], longest_up[p] + sibling);
    longest_up[u] = max(longest_up[u], 1 + sibling);
    if (best_sub[p][0].second == u)
      best_outside[u] = max(best_outside[u], best_sub[p][1].first);
    else
      best_outside[u] = max(best_outside[u], best_sub[p][0].first);
  }
  if (down_chains[p].cntChildren > 2) {
    info &dcp = down_chains[p];
    int siblings = (dcp.mxi == u) ? dcp.mx2 + dcp.mx3
                                  : ((dcp.mx2i == u) ? dcp.mx + dcp.mx3
                                                     : dcp.mx + dcp.mx2);
    best_outside[u] = max(best_outside[u], siblings);
  }
  for (int &v : adj[u])
    if (v != p) {
      dfsUp(v, u);
    }
}
int main() {
  cin.tie(NULL);
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v), adj[v].push_back(u);
  }
  dfsDown(1, 0), dfsUp(1, 0);
  long long ans = 0;
  for (int i = 1; i <= n; i++)
    ans = max(ans, 1ll * best_outside[i] * best_inSubtree[i]);
  printf("%lld\n", ans);
  return 0;
}
