#include #include using namespace std; using ll = long long; using mint = atcoder::modint998244353; struct problem_G{ int N; vector weight; vector parent_or_size; vector ans; problem_G(int n) : N(n), weight(N, 1 << 30), parent_or_size(N, -1), ans(N) {} int leader(int v){ while(parent_or_size[v] >= 0) v = parent_or_size[v]; return v; } void merge(int u, int v, int w){ int x = leader(u), y = leader(v); if(x == y) return; if(-parent_or_size[x] < -parent_or_size[y]) swap(x, y); ans[x] += ans[y] + mint(w) * parent_or_size[x] * parent_or_size[y]; parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; weight[y] = w; } int dist(int u, int v){ int ans = 0; while(u != v){ if(weight[u] < weight[v]) swap(u, v); ans = weight[v], v = parent_or_size[v]; if(v < 0) return -1; } return ans; } }; int main(){ ios::sync_with_stdio(false); cin.tie(0); int N, X, Q; cin >> N >> X >> Q; problem_G uf(N); int type, u, v, w; while(Q--){ cin >> type; if(type == 1){ cin >> v >> w; uf.merge(v, X, w); }else if(type == 2){ cin >> u >> v; int d = uf.dist(u, v); cout << d << '\n'; if(d != -1) (X += d) %= N; }else if(type == 3){ cin >> v; cout << uf.ans[uf.leader(v)].val() << '\n'; }else{ cin >> v; X += v; if(X >= N) X -= N; } } }