#include using namespace std; const long long MOD = 998244353; struct unionfind{ vector p; unionfind(int N){ p = vector(N, -1); } int root(int x){ if (p[x] < 0){ return x; } else { p[x] = root(p[x]); return p[x]; } } bool same(int x, int y){ return root(x) == root(y); } void unite(int x, int y){ x = root(x); y = root(y); if (x != y){ if (p[x] < p[y]){ swap(x, y); } p[y] += p[x]; p[x] = y; } } }; int main(){ int N, X, Q; cin >> N >> X >> Q; vector> g(N); vector c(N, 0); for (int i = 0; i < N; i++){ g[i].push_back(i); } vector> cnt0(N, vector(30, 0)); vector> cnt1(N, vector(30, 0)); for (int i = 0; i < N; i++){ for (int j = 0; j < 30; j++){ cnt0[i][j]++; } } unionfind UF(N); for (int i = 0; i < Q; i++){ int t; cin >> t; if (t == 1){ int v, w; cin >> v >> w; int u = X; int u2 = UF.root(u); w ^= c[u] ^ c[u2]; int v2 = UF.root(v); w ^= c[v] ^ c[v2]; UF.unite(u2, v2); if (UF.root(v2) == v2){ swap(u2, v2); } for (int j = 0; j < 30; j++){ if ((w >> j & 1) == 0){ cnt0[u2][j] += cnt0[v2][j]; cnt1[u2][j] += cnt1[v2][j]; } else { cnt0[u2][j] += cnt1[v2][j]; cnt1[u2][j] += cnt0[v2][j]; } } for (int x : g[v2]){ c[x] ^= w; g[u2].push_back(x); } g[v2].clear(); } if (t == 2){ int u, v; cin >> u >> v; if (!UF.same(u, v)){ cout << -1 << endl; } else { cout << (c[u] ^ c[v]) << endl; X += c[u] ^ c[v]; X %= N; } } if (t == 3){ int v; cin >> v; v = UF.root(v); long long ans = 0, d = 1; for (int j = 0; j < 30; j++){ ans += d * cnt0[v][j] % MOD * cnt1[v][j] % MOD; ans %= MOD; d *= 2; d %= MOD; } cout << ans << endl; } if (t == 4){ int value; cin >> value; X += value; X %= N; } } }