#include using namespace std::literals::string_literals; using i64 = std::int_fast64_t; using std::cout; using std::endl; using std::cin; template std::vector make_v(size_t a){return std::vector(a);} template auto make_v(size_t a,Ts... ts){ return std::vector(ts...))>(a,make_v(ts...)); } using namespace std; struct UnionFindUndo { vector< int > data; stack< pair< int, int > > history; UnionFindUndo(int sz) { data.assign(sz, -1); } bool unite(int x, int y) { x = find(x), y = find(y); history.emplace(x, data[x]); history.emplace(y, data[y]); if(x == y) return (false); if(data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; return (true); } int find(int k) { if(data[k] < 0) return (k); return (find(data[k])); } int size(int k) { return (-data[find(k)]); } void undo() { data[history.top().first] = history.top().second; history.pop(); data[history.top().first] = history.top().second; history.pop(); } void snapshot() { while(history.size()) history.pop(); } void rollback() { while(history.size()) undo(); } }; struct OfflineDynamicConnectivity { using edge = pair< int, int >; UnionFindUndo uf; int V, Q, segsz; vector< vector< edge > > seg; int comp; vector< pair< pair< int, int >, edge > > pend; map< edge, int > cnt, appear; OfflineDynamicConnectivity(int V, int Q) : uf(V), V(V), Q(Q), comp(V) { segsz = 1; while(segsz < Q) segsz <<= 1; seg.resize(2 * segsz - 1); } void insert(int idx, int s, int t) { auto e = minmax(s, t); if(cnt[e]++ == 0) appear[e] = idx; } void erase(int idx, int s, int t) { auto e = minmax(s, t); if(--cnt[e] == 0) pend.emplace_back(make_pair(appear[e], idx), e); } void add(int a, int b, const edge &e, int k, int l, int r) { if(r <= a || b <= l) return; if(a <= l && r <= b) { seg[k].emplace_back(e); return; } add(a, b, e, 2 * k + 1, l, (l + r) >> 1); add(a, b, e, 2 * k + 2, (l + r) >> 1, r); } void add(int a, int b, const edge &e) { add(a, b, e, 0, 0, segsz); } void build() { for(auto &p : cnt) { if(p.second > 0) pend.emplace_back(make_pair(appear[p.first], Q), p.first); } for(auto &s : pend) { add(s.first.first, s.first.second, s.second); } } void run(const function< void(int) > &f, int k = 0) { int add = 0; for(auto &e : seg[k]) { add += uf.unite(e.first, e.second); } comp -= add; if(k < segsz - 1) { run(f, 2 * k + 1); run(f, 2 * k + 2); } else if(k - (segsz - 1) < Q) { int query_index = k - (segsz - 1); f(query_index); } for(auto &e : seg[k]) { uf.undo(); } comp += add; } }; int main() { // input int n; scanf("%d", &n); assert(2 <= n and n <= (int)1e5); std::vector u(n - 1), v(n - 1), w(n - 1), T, X, Y; for(int i = 0; i < n - 1; i++) { scanf("%d%d%d", &u[i], &v[i], &w[i]); assert(0 <= u[i] and u[i] < n); assert(0 <= v[i] and v[i] < n); assert(0 <= w[i] and w[i] <= (int)1e5); T.push_back(0); X.push_back(u[i]); Y.push_back(v[i]); } T.push_back(2); X.push_back(-1); Y.push_back(-1); int q; scanf("%d", &q); i64 K = 0; for(int i = 0; i < q; i++) { int type; scanf("%d", &type); assert(type == 1 or type == 2); if(type == 1) { int u, v, w, x; scanf("%d%d%d%d", &u, &v, &w, &x); assert(0 <= u and u < n); assert(0 <= v and v < n); assert(0 <= w and w < n); assert(0 <= x and x <= (int)1e5); assert(u != v and v != w); T.push_back(1); X.push_back(u); Y.push_back(v); T.push_back(0); X.push_back(v); Y.push_back(w); T.push_back(2); X.push_back(-1); Y.push_back(-1); } else { int k; scanf("%d", &k); assert(1 <= k and k <= n); K += k; std::set st; for(int j = 0; j < k; j++) { int x; scanf("%d", &x); assert(0 <= x and x < n); st.insert(x); } assert(st.size() == k); } } assert(1 <= K and K <= (int)1e5); OfflineDynamicConnectivity odc(n, T.size()); for(int i = 0; i < T.size(); i++) { if(T[i] == 0) { odc.insert(i, X[i], Y[i]); } else if(T[i] == 1) { odc.erase(i, X[i], Y[i]); } } odc.build(); odc.run([&](int k) { if(T[k] == 2) assert(odc.comp == 1); }); printf("U K U N I C H I A\n"); return 0; }