Problem:
Score : 1100 points

Problem Statement

We have a tree G with N vertices numbered 1 to N.
The i-th edge of G connects Vertex a_i and Vertex b_i.

Consider adding zero or more edges in G, and let H be the graph resulted.

Find the number of graphs H that satisfy the following conditions, modulo 998244353.

H does not contain self-loops or multiple edges.

The diameters of G and H are equal.

For every pair of vertices in H that is not directly connected by an edge, the addition of an edge directly connecting them would reduce the diameter of the graph.

Constraints

3 \le N \le 2 \times 10^5

1 \le a_i, b_i \le N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
\vdots
a_{N-1} b_{N-1}

Output

Print the answer.

Sample Input 1

6
1 6
2 1
5 2
3 4
2 3

Sample Output 1

3

For example, adding the edges (1, 5), (3, 5) in G satisfies the conditions.

Sample Input 2

3
1 2
2 3

Sample Output 2

1

The only graph H that satisfies the conditions is G.

Sample Input 3

9
1 2
2 3
4 2
1 7
6 1
2 5
5 9
6 8

Sample Output 3

27

Sample Input 4

19
2 4
15 8
1 16
1 3
12 19
1 18
7 11
11 15
12 9
1 6
7 14
18 2
13 12
13 5
16 13
7 1
11 10
7 17

Sample Output 4

78732

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

void solve(std::istream &in, std::ostream &out);

int main() {
#ifdef LOCAL
  freopen("../IO/f.in", "r", stdin);
//  freopen("../IO/f.out", "w", stdout);
#else
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
#endif
  solve(std::cin, std::cout);
  return 0;
}

int md = 998244353;
constexpr int N = (int)2e5 + 499;
vector<int> g[N];
int par[N], dp[N][3][3];
// dp[V][A][B] - number of ways to choose labels in subtree of V such that |label(v) - label(u)| <= 1 for adjacent vertices
// and there are exactly A candidates for label D/2 and B candidates for label -D/2
// since we are interested in labeling with exactly one vertex of both types, it's enough to count number of labelings with more than one candidate instead of an exact number.
// since root has value 0, the problem is reduced to assigning edge weights.
void dfs1(int v, int p, int d, int &cand, int &mx) {
  par[v] = p;
  if (d > mx)
    mx = d, cand = v;
  for (int u : g[v])
    if (u != p)
      dfs1(u, v, d + 1, cand, mx);
}

void treedp(int v, int p, int left) {
  if (left == 0) {
    // depending on the parent-edge value this vertex-candidate may result in states (1, 0), (0, 0), and(0, 1)
    // so it's ok to say that this vertex is a candidate for both -D/2 and D/2
    dp[v][1][1] = 1;
  } else {
    dp[v][0][0] = 1;
  }
  for (int u : g[v]) {
    if (u == p) continue;
    treedp(u, v, left - 1);
    int ndp[3][3] = {};
    for (int a1 : {0, 1, 2}) {
      for (int b1 : {0, 1, 2}) {
        for (int a2 : {0, 1, 2}) {
          for (int b2 : {0, 1, 2}) {
            // +1
            ndp[min(a1 + a2, 2)][b1] = (ndp[min(a1 + a2, 2)][b1] + (int64_t) dp[v][a1][b1] * dp[u][a2][b2] % md) % md;
            // 0
            ndp[a1][b1] = (ndp[a1][b1] + (int64_t) dp[v][a1][b1] * dp[u][a2][b2] % md) % md;
            // -1
            ndp[a1][min(b1 + b2, 2)] = (ndp[a1][min(b1 + b2, 2)] + (int64_t) dp[v][a1][b1] * dp[u][a2][b2] % md) % md;
          }
        }
      }
    }
    for (int a1 : {0, 1, 2}) {
      for (int a2 : {0, 1, 2}) {
        dp[v][a1][a2] = ndp[a1][a2];
      }
    }
  }
}

void solve(std::istream &in, std::ostream &out) {
  int n;
  in >> n;
  for (int i = 0, u, v; i < n - 1; ++i) {
    in >> u >> v;
    --u;
    --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  int u, v, mx = 0;
  dfs1(0, -1, 0, u, mx);
  mx = 0;
  dfs1(u, -1, 0, v, mx);
  for (int i = 0; i < mx / 2; ++i) {
    v = par[v];
    u = par[v];
  }
  if (mx % 2 == 1) {
    treedp(v, u, mx / 2);
    treedp(u, v, mx / 2);
    // in fact, any labeling that has at least one -(D - 1)/2 path is ok too
    // because none of them can form a diameter with (D - 1)/2 path as the resulting path will have length D-1 without an edge u-v
    // division by 2 in not needed since it's only (D-1)/2 path that will be paired with the other half
    // if we multiply signs by -1 the other part will be paired, and thus another diameter will be formed
    int x = ((int64_t) dp[v][1][0] + dp[v][1][1] + dp[v][1][2]) % md;
    int y = ((int64_t) dp[u][1][0] + dp[u][1][1] + dp[u][1][2]) % md;
    out << (int64_t) x * y % md << '\n';
  } else {
    treedp(v, -1, mx / 2);
    // for a fixed diameter we can multiply labels by -1 and still have a valid labeling with the same diameter
    // thus dividing by 2 is needed
    out << (int64_t) dp[v][1][1] * (md + 1) / 2 % md << '\n';
  }
}