using System; using static System.Console; using System.Linq; using System.Collections.Generic; using System.Globalization; class Program { static int NN => int.Parse(ReadLine()); static int[] NList => ReadLine().Split().Select(int.Parse).ToArray(); static int[][] NArr(long n) => Enumerable.Repeat(0, (int)n).Select(_ => NList).ToArray(); public static void Main() { Solve(); } static void Solve() { var c = NList; var (n, q) = (c[0], c[1]); var map = NArr(q); var uf = new UnionFindTree(n + q); var tree = new List[n + q]; for (var i = 0; i < tree.Length; ++i) tree[i] = new List(); var refs = new int[n + q]; for (var i = 0; i < q; ++i) { if (map[i][0] == 1) { var ar = uf.GetRoot(map[i][1] - 1); var br = uf.GetRoot(map[i][2] - 1); uf.Unite(n + i, ar); tree[n + i].Add(ar); ++refs[ar]; if (uf.Unite(n + i, br)) { tree[n + i].Add(br); ++refs[br]; } } } var dfst = new List(); for (var i = 0; i < n + q; ++i) { if (refs[i] == 0) { DFS(i, -1, tree, dfst); } } var pos1 = Enumerable.Repeat(-1, n + q).ToArray(); var pos2 = new int[n + q]; for (var i = 0; i < dfst.Count; ++i) { if (pos1[dfst[i]] < 0) pos1[dfst[i]] = i; else pos2[dfst[i]] = i; } var ft = new FenwickTree(dfst.Count); uf = new UnionFindTree(n + q); var ans = new List(); for (var i = 0; i < q; ++i) { if (map[i][0] == 1) { var ar = uf.GetRoot(map[i][1] - 1); var br = uf.GetRoot(map[i][2] - 1); uf.Unite(n + i, ar); uf.Unite(n + i, br); } else if (map[i][0] == 2) { var ar = uf.GetRoot(map[i][1] - 1); ft.Add(pos1[ar], map[i][2]); ft.Add(pos2[ar], -map[i][2]); } else { ans.Add(ft.Sum(pos1[map[i][1] - 1])); } } WriteLine(string.Join("\n", ans)); } static void DFS(int cur, int prev, List[] tree, List dfst) { dfst.Add(cur); foreach (var next in tree[cur]) { if (next == prev) continue; DFS(next, cur, tree, dfst); } dfst.Add(cur); } class UnionFindTree { int[] roots; public UnionFindTree(int size) { roots = new int[size]; for (var i = 0; i < size; ++i) roots[i] = -1; } public int GetRoot(int a) { if (roots[a] < 0) return a; return roots[a] = GetRoot(roots[a]); } public bool IsSameTree(int a, int b) { return GetRoot(a) == GetRoot(b); } public bool Unite(int a, int b) { var x = GetRoot(a); var y = GetRoot(b); if (x == y) return false; if (x < y) { var tmp = x; x = y; y = tmp; } roots[x] += roots[y]; roots[y] = x; return true; } public int GetSize(int a) { return -roots[GetRoot(a)]; } } class FenwickTree { int size; long[] tree; public FenwickTree(int size) { this.size = size; tree = new long[size + 2]; } public void Add(int index, int value) { ++index; for (var x = index; x <= size; x += (x & -x)) tree[x] += value; } /// 先頭からindexまでの和(include index) public long Sum(int index) { if (index < 0) return 0; ++index; var sum = 0L; for (var x = index; x > 0; x -= (x & -x)) sum += tree[x]; return sum; } public long Get(int index) { if (index == 0) return Sum(0); return Sum(index) - Sum(index - 1); } /// Sum(x) >= value となる最小のxを求める // 各要素は非負であること public int LowerBound(long value) { if (value < 0) return -1; var x = 0; var b = 1; while (b * 2 <= size) b <<= 1; for (var k = b; k > 0; k >>= 1) { if (x + k <= size && tree[x + k] < value) { value -= tree[x + k]; x += k; } } return x; } } }