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: Time Limit Exceeded)

#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a),_ed=(b);i<=_ed;++i)
#define DREP(i,a,b) for(int i=(a),_ed=(b);i>=_ed;--i)
#define mp(x,y) make_pair((x),(y))
#define sz(x) (int)(x).size()
#define pb push_back
typedef long long ll;
typedef pair<int,int> pii;
inline int read(){
    register int x=0,f=1;register char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
    return f?x:-x;
}

const int N=2e5+5,mod=998244353;
int n,c[2],mxd[N],f[N][3][3],g[3][3];
vector<int> E[N];
inline void inc(int& x,int y){x=x+y<mod?x+y:x+y-mod;}

namespace getcore{
	int d[N],fa[N],stk[N],tp,tmp;
	void dfs(int u,int pa,int dis,int& rt){
		d[u]=dis,fa[u]=pa;if(d[u]>d[rt])rt=u;
		for(int v:E[u]){
			if(v==pa)continue;
			dfs(v,u,dis+1,rt);
		}
	}
	void Main(){
		dfs(1,0,0,tmp);
		dfs(tmp,0,0,tmp);
		while(tmp)stk[++tp]=tmp,tmp=fa[tmp];
		c[0]=stk[(tp+1)>>1];
		if(~tp&1)c[1]=stk[((tp+1)>>1)+1];//想清楚啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
	}
}

int dfs(int u,int pa,int dep){
	mxd[u]=dep;
	for(int v:E[u]){
		if(v==pa||v==c[0]||v==c[1])continue;
		mxd[u]=max(mxd[u],dfs(v,u,dep+1));
	}
	if(mxd[u]==dep)f[u][1][1]=1;
	else f[u][0][0]=1;
	for(int v:E[u]){
		if(v==pa||v==c[0]||v==c[1])continue;
		REP(i,0,2)REP(j,0,2)g[i][j]=0;
		REP(a,0,2)REP(b,0,2)REP(p,0,2)REP(q,0,2){
			int flg=mxd[u]==mxd[v];
			int s=a,t=b,val=1ll*f[u][a][b]*f[v][p][q]%mod;
			inc(g[s][t],val);
			s=flg?min(2,a+p):a,t=b;
			inc(g[s][t],val);
			s=a,t=flg?min(2,b+q):b;
			inc(g[s][t],val);
		}
		REP(i,0,2)REP(j,0,2)f[u][i][j]=g[i][j];
	}
	return mxd[u];
}

int main(){
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
	n=read();
	REP(i,1,n-1){
		int u=read(),v=read();
		E[u].pb(v),E[v].pb(u);
	}
	getcore::Main();
	int sum=0;
	dfs(c[0],0,0);
	if(!c[1])
		sum=f[c[0]][1][1];
	else{
		dfs(c[1],0,0);
		REP(i,0,2)REP(j,0,2)
			inc(sum,1ll*f[c[0]][1][i]*f[c[1]][j][1]%mod);
		REP(i,0,2)REP(j,0,2)
			inc(sum,1ll*f[c[0]][i][1]*f[c[1]][1][j]%mod);
	}
	sum=1ll*sum*(mod+1)/2%mod;
	printf("%d\n",sum);
	return 0;
}