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

#define int int64_t
#define endl '\n'
#define vi vector<int>
#define vvi vector<vi>
#define pi pair<int, int>
#define vpi vector<pi>
#define F0(n, i) for(int i = 0; i < n; i++)
#define F1(n, i) for(int i = 1; i <= n; i++)
#define each(a) for(auto& e: a)
#define arr(a) { each(a) cerr << e << ' '; cerr << endl; }
#define mtx(m) { each(m) arr(e); cerr << endl; }

template<typename T>
class segtree {
public:
	vector<T> t;
	int n;
	T def;
	function<T(T, T)> fx;
	void build(int _n, T _def, function<T(T, T)> _fx) {
		n = _n; def = _def; fx = _fx;
		t.assign(2 * n, def);
		for(int i = n - 1; i; i--) t[i] = fx(t[i * 2], t[i * 2 + 1]);
	}
	void build(vector<T>& src, T _def, function<T(T, T)> _fx) {
		n = src.size(); def = _def; fx = _fx;
		t.assign(2 * n, def);
		F0(n, i) t[i + n] = src[i];
		for(int i = n - 1; i; i--) t[i] = fx(t[i * 2], t[i * 2 + 1]);
	}
	void update(int i, T val) {
		for(t[i += n] = val; i > 1; ) {
			i /= 2;
			t[i] = fx(t[i * 2], t[i * 2 + 1]);
		}
	}
	// this query made on [l, r)
	T query(int l, int r) {
		T ans = def;
		for(l += n, r += n; l < r; l /= 2, r /= 2) {
			if(l % 2) ans = fx(ans, t[l++]);
			if(r % 2) ans = fx(ans, t[--r]);
		}
		return ans;
	}
};

int exp(int x, int p, int m) {
	int ans = 1;
	for(int res = x, i = 0; (1LL << i) <= p; i++, res = res * res % m) {
		if(x & (1LL << i)) {
			ans = (ans * res) % m;
		}
	}
	return ans;
}

int imod(int x, int m) {
	return exp(x, m - 2, m);
}

void solve() {
	int n, m, x;
	cin >> n >> m >> x;
	const int M = 998244353;
	vvi G(n);
	F0(n - 1, _) {
		int u, v;
		cin >> u >> v;
		u--; v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	mtx(G);
	vi a(n);
	F0(n, i) cin >> a[i], a[i]--;
	vi btf;
	int A = 5; // max size of btf array
	queue<pi> q;
	q.push({0, 0});
	while(!q.empty()) {
		pi p = q.front();
		q.pop();
		if(btf.size() > A) break ;
		F0(10, i) {
			int sum = p.second + i * i, num = ((p.first * 10 % M) + i) % M;
			if(sum <= x && num) {
				q.push({num, sum});
				btf.push_back(num);
			}
		}
	}
	arr(btf);
	int t = 0;
	vi vis(n), tin(n), tout(n);
	function<void(int)> dfs = [&](int i) {
		vis[i] = 1;
		tin[i] = t++;
		each(G[i]) {
			if(!vis[e]) {
				dfs(e);
			}
		}
		tout[i] = t++;
	};
	dfs(0);
	vi euler(n * 2);
	F0(n, i) euler[tin[i]] = i, euler[tout[i]] = i;
	arr(euler);
	segtree<int> Sum;
	Sum.build(n * 2, 0, [&](int x, int y) { return (x + y) % M; });
	F0(n, i) Sum.update(tin[i], btf[a[i]]);
	while(m--) {
		int t;
		cin >> t;
		if(t == 1) {
			int i, v;
			cin >> i >> v;
			i--; v--;
			a[i] = v;
			Sum.update(tin[i], btf[v]);
		} else {
			int i;
			cin >> i;
			i--;
			arr(a);
			arr(Sum.t);
			cout << Sum.query(tin[i], tout[i] + 1) << endl;
		}
	}
}

int32_t main() {
	int t = 1;
	// cin >> t;
	while(t--) {
		solve();
		cout << endl;
	}
	return 0;
}