// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

cat mod = 998244353;
vector<cat> pw3(200010);

void DFS_dp(int R, int par, int dep, int D, auto & G, auto & sz, vector<cat> * dp) {
	if(dep == D) {
		dp[0][R] = 2, dp[1][R] = 1;
		return;
	}
	dp[0][R] = 1;
	for(auto s : G[R]) if(s != par) {
		DFS_dp(s, R, dep+1, D, G, sz, dp);
		sz[R] += sz[s];
		dp[1][R] = (dp[1][R] * dp[0][s] + dp[0][R] * dp[1][s]) % mod;
		dp[0][R] = dp[0][R] * dp[0][s] % mod;
	}
	dp[0][R] = (dp[0][R] + pw3[sz[R]-1] * 2) % mod;
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N;
	cin >> N;
	pw3[0] = 1;
	for(int i = 1; i <= N; i++) pw3[i] = pw3[i-1] * 3 % mod;
	vector< vector<int> > G(N);
	for(int i = 0; i < N-1; i++) {
		int u, v;
		cin >> u >> v;
		G[--u].push_back(--v);
		G[v].push_back(u);
	}
	vector<int> dist[2];
	dist[0] = vector<int>(N, N);
	dist[0][0] = 0;
	queue<int> q;
	q.push(0);
	while(!q.empty()) {
		for(auto v : G[q.front()]) if(dist[0][v] == N) {
			dist[0][v] = dist[0][q.front()]+1;
			q.push(v);
		}
		q.pop();
	}
	int max_dv = 0;
	for(int i = 0; i < N; i++)
		if(dist[0][max_dv] < dist[0][i]) max_dv = i;
	dist[1] = vector<int>(N, N);
	dist[1][max_dv] = 0;
	q.push(max_dv);
	vector<int> par(N);
	while(!q.empty()) {
		for(auto v : G[q.front()]) if(dist[1][v] == N) {
			dist[1][v] = dist[1][q.front()]+1;
			par[v] = q.front();
			q.push(v);
		}
		q.pop();
	}
	int other_end = 0;
	for(int i = 0; i < N; i++)
		if(dist[1][other_end] < dist[1][i]) other_end = i;
	int D = dist[1][other_end];
	int R = other_end;
	for(int i = 0; i < D/2; i++) R = par[R];
	if(D%2) {
		G.push_back({R, par[R]});
		G[R].erase(find(begin(G[R]), end(G[R]), par[R]));
		G[par[R]].erase(find(begin(G[par[R]]), end(G[par[R]]), R));
		G[R].push_back(N);
		G[par[R]].push_back(N);
		R = N;
		N++, D++;
	}
	D /= 2;
	vector<cat> dp[2] = {vector<cat>(N, 0), vector<cat>(N, 0)};
	vector<int> sz(N, 1);
	DFS_dp(R, R, 0, D, G, sz, dp);
	cat ans[3] = {1, 0, 0};
	for(auto s : G[R]) {
		dp[0][s] -= (pw3[sz[s]]-dp[0][s]);
		if(dp[0][s] < 0) dp[0][s] += mod;
		if(dp[0][s] >= mod) dp[0][s] -= mod;
		if(dp[0][s] < 0) dp[0][s] += mod;
		if(dp[0][s] >= mod) dp[0][s] -= mod;
		ans[2] = (ans[1] * dp[1][s] + ans[2] * dp[0][s]) % mod;
		ans[1] = (ans[0] * dp[1][s] + ans[1] * dp[0][s]) % mod;
		ans[0] = (ans[0] * dp[0][s]) % mod;
	}
	cout << ans[2] << "\n";
	return 0;
}

// look at my code
// my code is amazing


Measured memory_bytes: 26544