// Slower C++ solution:
#include<cctype>

#include<cstdio>

#include<vector>

#include<cstring>

const int N=300007,P=998244353,i2=P-P/2;

int m,root,len,fa[N],dia[N],f[N][3][3],g[3][3];std::vector<int>e[N];

void inc(int&a,int b){a+=b-P,a+=a>>31&P;}

int mul(int a,int b){return 1ll*a*b%P;}

int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}

void dfs(int u,int dep)

{

    if(dep>len) len=dep,root=u;

    for(int v:e[u]) if(v^fa[u]) fa[v]=u,dfs(v,dep+1);

}

void dp(int u,int fa,int d)

{

    (d==m/2? f[u][1][1]:f[u][0][0])=1;

    for(int v:e[u])

    {

	if(v==fa) continue;

	dp(v,u,d+1),memset(g,0,36);

	for(int x=0;x<3;++x) for(int y=0;y<3;++y) for(int p=0;p<3;++p) for(int q=0;q<3;++q) for(int k=0,r,t;k<3;++k) r=std::min(2,x+p*(k==1)),t=std::min(2,y+q*(k==2)),inc(g[r][t],mul(f[u][x][y],f[v][p][q]));

	memcpy(f[u],g,36);

    }

}

int main()

{

    int n=read(),p,q;

    for(int i=1,u,v;i<n;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);

    dfs(1,1),memset(fa+1,0,n<<2),len=0,dfs(root,1);

    for(int i=root;i;i=fa[i]) dia[++m]=i;

    if(m&1) p=dia[m/2+1],dp(p,0,0),printf("%d",mul(i2,f[p][1][1]));

    else p=dia[m/2],q=dia[m/2+1],dp(p,q,1),dp(q,p,1),printf("%d",mul((1ll*f[p][1][0]+f[p][1][1]+f[p][1][2])%P,(1ll*f[q][1][0]+f[q][1][1]+f[q][1][2])%P));

}


// Faster C++ solution for the same problem (measured speedup: 9.437536109203503x):
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;

const int maxn = 2e5 + 5, mod = 998244353;



inline int gi()

{

	char c = getchar();

	while (c < '0' || c > '9') c = getchar();

	int sum = 0;

	while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar();

	return sum;

}



inline void inc(int &a, int b) {a += b; if (a >= mod) a -= mod;}



int n, rt, len, fa[maxn], ch[maxn];



struct edge

{

	int to, next;

} e[maxn * 2];

int h[maxn], tot;

int md[maxn], f[maxn][3][3], g[3][3];



inline void add(int u, int v)

{

	e[++tot] = (edge) {v, h[u]}; h[u] = tot;

	e[++tot] = (edge) {u, h[v]}; h[v] = tot;

}



void dfs1(int u, int d)

{

	if (d > len) rt = u, len = d;

	md[u] = d;

	for (int i = h[u], v; v = e[i].to, i; i = e[i].next)

		if (v != fa[u]) fa[v] = u, dfs1(v, d + 1), md[u] = max(md[u], md[v]);

}



void dfs2(int u, int d)

{

	(md[u] == d ? f[u][1][1] : f[u][0][0]) = 1;

	for (int i = h[u], v; v = e[i].to, i; i = e[i].next)

		if (v != fa[u]) {

			fa[v] = u; dfs2(v, d + 1);

			memset(g, 0, sizeof(g));

			for (int a = 0; a <= 2; ++a)

				for (int b = 0; b <= 2; ++b)

					if (f[u][a][b])

						for (int c = 0; c <= 2; ++c)

							for (int d = 0; d <= 2; ++d)

								if (f[v][c][d])

									for (int t = -1; t <= 1; ++t)

										inc(g[min(2, a + (md[v] == md[u] && t == 1) * c)][min(2, b + (md[v] == md[u] && t == -1) * d)], (ll)f[u][a][b] * f[v][c][d] % mod);

			memcpy(f[u], g, sizeof(f[u]));

		}

}



int main()

{

	n = gi();

	for (int i = 1; i < n; ++i) add(gi(), gi());



	dfs1(1, 0);

	fa[rt] = 0; len = 0; dfs1(rt, 0);

	for (int i = 0, x = rt; x; x = fa[x]) ch[i++] = x;



	if (~len & 1) {

		int x = ch[len >> 1];

		fa[x] = 0, dfs1(x, 0);

		dfs2(x, 0);

		printf("%lld\n", (ll)f[x][1][1] * (mod + 1) / 2 % mod);

	}

	else {

		int x = ch[len >> 1], y = ch[len + 1 >> 1];

		fa[x] = y; fa[y] = x;

		dfs1(x, 0); dfs2(x, 0);

		dfs1(y, 0); dfs2(y, 0);

		printf("%lld\n", ((ll)f[x][1][0] + f[x][1][1] + f[x][1][2]) * ((ll)f[y][1][0] + f[y][1][1] + f[y][1][2]) % mod);

	}

	

	return 0;

}