#include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef vector vi; template bool chmin(H& v1, const H v2) { if (v1 > v2) { v1 = v2; return true; } return false; } template bool chmax(H& v1, const H v2) { if (v1 < v2) { v1 = v2; return true; } return false; } template void read(H& head) { cin >> head; } template void read(H& head, T& ...tail) { cin >> head; read(tail...); } template void write(H head) { cout << head << '\n'; } template void write(H head, T ...tail) { cout << head << " "; write(tail...); } template void die(T ...tok) { write(tok...); exit(0); } struct Dsu { int dsu[500005]; int v[500005]; Dsu() { fill(dsu, dsu + 500005, -1), fill(v, v + 500005, 0); } int find(int x) { return dsu[x] < 0 ? x : find(dsu[x]); } void merge(int a, int b) { a = find(a), b = find(b); if (a == b) return; // union by rank int ra = -dsu[a], rb = -dsu[b]; if (ra < rb) swap(a, b); // glue u <- v dsu[a] += dsu[b]; dsu[b] = a; while (a >= 0) { v[b] -= v[a]; a = dsu[a]; } } }; Dsu dsu; int main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); int n, q; read(n, q); rep(i, 0, q) { int t, a, b; read(t, a, b); if (t == 1) { dsu.merge(a, b); } else if (t == 2) { a = dsu.find(a); dsu.v[a] += b; } else if (t == 3) { int cv = 0; while (a >= 0) { cv += dsu.v[a]; a = dsu.dsu[a]; } write(cv); } } }