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>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int mo=998244353;
const int N=200005;
int n;
vector<int> e[N];
int q[N],dS[N],dT[N];
int mx[N],f[N][9],tmp[9];
int bfs(int S,int *d){
	For(i,1,n) d[i]=-1;
	int h=0,t=1;
	q[1]=S; d[S]=0;
	while (h!=t){
		int x=q[++h];
		for (auto i:e[x])
			if (d[i]==-1){
				d[i]=d[x]+1;
				q[++t]=i;
			}
	}
	return q[t];
}
void DP(int x,int fa){
	mx[x]=0;
	for (auto i:e[x]) if (i!=fa)
		DP(i,x),mx[x]=max(mx[x],mx[i]);
	f[x][mx[x]==0?4:0]=1;
	for (auto i:e[x]) if (i!=fa){
		memset(tmp,0,sizeof(tmp));
		For(j,0,8) For(k,0,8){
			int ek=(mx[i]==mx[x]?k:0);
			int nv=min(j%3+ek%3,2)+3*min(j/3+ek/3,2);
			tmp[nv]=(tmp[nv]+1ll*f[x][j]*f[i][k])%mo;
		} 
		memcpy(f[x],tmp,sizeof(f[x]));
	}
	//cout<<mx[x]<<endl;
	if (fa){
		memset(tmp,0,sizeof(tmp));
		For(j,0,8){
			int v1=0,v2=j%3,v3=j/3*3;
			tmp[v1]=(tmp[v1]+f[x][j])%mo;
			tmp[v2]=(tmp[v2]+f[x][j])%mo;
			tmp[v3]=(tmp[v3]+f[x][j])%mo;
		}
		memcpy(f[x],tmp,sizeof(tmp));
		++mx[x];
	}
}
int main(){
	scanf("%d",&n);
	For(i,1,n-1){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].PB(y); e[y].PB(x);
	}
	int S=bfs(1,dS);
	int T=bfs(S,dS);
	bfs(T,dT);
	For(i,1,n)
		if (dS[i]==dS[T]/2||dT[i]==dT[S]/2)
			if (dS[i]+dT[i]==dT[S])
				q[++*q]=i;
	if (*q==1){
		DP(q[1],0);
		printf("%lld\n",1ll*f[q[1]][4]*(mo+1)/2%mo);
	}
	else{
		DP(q[2],q[1]);
		DP(q[1],q[2]);
		printf("%lld\n",1ll*f[q[1]][1]*f[q[2]][3]%mo);
	}
}
/*
    5
    |
4-3-2-1-6

f[i][0/1][0/1]的方案数
*/