Problem:
Bichrome Tree Connectivity
木が与えられます。
はじめ、すべての頂点は白いです。
白い頂点の色を反転すると黒になり、黒い頂点の色を反転すると白になります。
二種類のクエリを処理してください。
一種類目のクエリでは、頂点
v
の色を反転します。
二種類目のクエリでは、白い頂点
v
から白い頂点とそれらを結ぶ辺だけを使ってたどり着ける頂点の個数を答えます。
入力
N Q
a_1 b_1
a_2 b_2
:
a_{n-1} b_{n-1}
t_1 v_1
t_2 v_2
:
t_q v_q
t_i
が
1
のとき一種類目のクエリ、
2
のとき二種類目のクエリであることを表す。
出力
ans_1
ans_2
:
ans_k
二種類目のクエリに対する答えを順に出力せよ。
制約
1 \leq N,Q \leq 10^5
1 \leq a_i,b_i \leq N
1 \leq t_i \leq 2
1 \leq v_i \leq N
与えられるグラフは木である。
t_i=2
のとき、頂点
v_i
は必ず白である。
入力例
10 3
1 2
2 5
2 6
1 4
1 3
3 7
3 8
3 9
9 10
1 3
2 1
2 8
出力例
5
1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long

#define FOR(I, L, R) for(int I(L) ; I <= (int)R ; ++I)
#define FOD(I, R, L) for(int I(R) ; I >= (int)L ; --I)
#define FOA(I, A) for(auto &I : A)

#define print(A,L,R) FOR(OK, L, R){if(A[OK]<=-oo / 10||A[OK]>=oo)cout<<"- ";else cout<<A[OK]<<' ';}cout<<'\n';
#define prints(A) FOA(OK, A){cout<<OK<<' ';}cout << '\n';
#define printz(A,L,R) FOR(OK, 0, L){FOR(KO, 0, R){if(A[OK][KO]>-oo&&A[OK][KO]<oo)cout<<A[OK][KO]<<' ';else cout << "- ";} cout << '\n';}cout << '\n';

#define fs first
#define sd second
#define ii pair<int,int>
#define iii pair<int, ii>
#define all(A) A.begin(), A.end()
#define quickly cin.tie(0) -> ios_base::sync_with_stdio(0);

const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const int oo = 1e18;

int n, q, vt;
int a[N], b[N], ans[N];
vector<vector<int>> query[2];
vector<int> g[N];

/// HLD
int el;
int st[N], en[N], sz[N], h[N], e[N];
int top[N], nxt[N], parent[N];

void DFS(int u, int par){
        sz[u] = 1;

        FOA(v, g[u]){
                if(v == par){
                        continue;
                }
                parent[v] = u;
                h[v] = h[u] + 1;
                DFS(v, u);

                sz[u] += sz[v];

                if(sz[nxt[u]] < sz[v]){
                        nxt[u] = v;
                }
        }
}

void HLD(int u, int par, int tp){
        st[u] = ++el;
        top[u] = tp;
        e[el] = u;

        if(nxt[u]){
                HLD(nxt[u], u, tp);
        }

        FOA(v, g[u]){
                if(v == par || v == nxt[u]){
                        continue;
                }
                HLD(v, u, v);
        }

        en[u] = el;
}

struct node{
        int mn, mx, cnt, lazy;

        node(){mn = oo; mx = -oo; cnt = lazy = 0;}
        node(int _mn, int _cnt){
                mn = mx = _mn;
                cnt = _cnt;
                lazy = 0;
        }

        node operator + (const node &t) const{
                node _new;

                if(mn == t.mn){
                        _new.mn = mn;
                        _new.cnt = cnt + t.cnt;
                }
                else if(mn > t.mn){
                        _new.mn = t.mn;
                        _new.cnt = t.cnt;
                }
                else{
                        _new.mn = mn;
                        _new.cnt = cnt;
                }
                _new.mx = max(mx, t.mx);

                return _new;
        }
};

struct Segment_tree{
        node sg[N << 2];

        void build(int id, int l, int r){
                sg[id] = node(0, 1);

                if(l == r){
                        return;
                }
                int mid = (l + r) >> 1;

                build(id << 1, l, mid);
                build(id << 1 | 1, mid + 1, r);

                sg[id] = sg[id << 1] + sg[id << 1 | 1];
        }

        void push_down(int id, int l, int r){
                if(sg[id].lazy){
                        int &val = sg[id].lazy;

                        sg[id << 1].lazy += val;
                        sg[id << 1 | 1].lazy += val;

                        sg[id << 1].mn += val;
                        sg[id << 1 | 1].mn += val;

                        sg[id << 1].mx += val;
                        sg[id << 1 | 1].mx += val;

                        val = 0;
                }
        }

        void update(int id, int l, int r, int u, int v, int val){
                if(l > v || r < u){
                        return;
                }
                if(u <= l && r <= v){
                        sg[id].mn += val;
                        sg[id].mx += val;
                        sg[id].lazy += val;
                        return;
                }

                push_down(id, l, r);

                int mid = (l + r) >> 1;
                update(id << 1, l, mid, u, v, val);
                update(id << 1 | 1, mid + 1, r, u, v, val);

                sg[id] = sg[id << 1] + sg[id << 1 | 1];
        }

        node get(int id, int l, int r, int u, int v){
                if(l > v || r < u){
                        return node();
                }
                if(u <= l && r <= v){
                        return sg[id];
                }

                push_down(id, l, r);

                int mid = (l + r) >> 1;
                return get(id << 1, l, mid, u, v) + get(id << 1 | 1, mid + 1, r, u, v);
        }

        int walk(int id, int l, int r, int u, int v, int k){
                if(l > v || r < u){
                        return oo;
                }
                if(l == r){
                        return l;
                }

                int mid = (l + r) >> 1;
                int res = oo;

                push_down(id, l ,r);

                if(sg[id << 1].mx >= k){
                        res = walk(id << 1, l, mid, u, v, k);
                }
                if(res == oo && sg[id << 1 | 1].mx >= k){
                        res = walk(id << 1 | 1, mid + 1, r, u, v, k);
                }

                return res;
        }
} sg;

int farest(int u){
        int res = st[u], pre = st[u];
        int k = sg.get(1, 1, n, st[u], st[u]).mn;

        if(k == 0) return 1;

        while(top[u] != 1){
                int val = sg.walk(1, 1, n, st[top[u]], st[u], k);
                if(val != oo){
                        res = min(res, (val == st[u] ? pre : val + 1));
                }
                else{
                        return res;
                }

                pre = top[u];
                u = parent[top[u]];
        }

        int val = sg.walk(1, 1, n, 1, st[u], k);

        res = min(res, (val == st[u] ? pre : val + 1));

        return res;
}


signed main(){ quickly
        cin >> n >> q;

        FOR(i, 2, n){
                int u, v;
                cin >> u >> v;

                g[u].push_back(v);
                g[v].push_back(u);
        }

        DFS(1, -1);
        HLD(1, -1, 1);

        sg.build(1, 1, n);

        FOR(i, 1, q){
                int type, u;
                cin >> type >> u;

                if(type == 1){
                        int h = (a[u] == 0 ? 1 : -1);
                        sg.update(1, 1, n, st[u], en[u], h);
                        a[u] ^= 1;
                }
                else{
                        int x = e[farest(u)];
                        cout << sg.get(1, 1, n, st[x], en[x]).cnt << '\n';
                }
        }
}
accuracy: 0.2
time_ms: 80
memory_kb: 30428
final_rank: 20

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

#line 2 "library/DataStructure/unionfind.hpp"

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */
#line 6 "sol.cpp"

int main() {
    int n, Q;
    read(n, Q);
    vector g(n, vector<int>());
    rep(_, 0, n - 1) {
        int x, y;
        read(x, y);
        x--, y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    using P = pair<int, int>;
    vector<P> que;
    rep(i, 0, Q) {
        int t, v;
        read(t, v);
        v--;
        que.push_back({t, v});
    }

    int SQ = max<int>(1, sqrtl(Q));
    // int SQ = Q;
    int L = 0;
    vector<int> col(n); // 0:white
    vector<int> out;
    while (L < Q) {
        int R = min(Q, L + SQ);

        vector<int> mark(n);
        rep(i, L, R) {
            mark[que[i].second] = 1;
        }
        UnionFind uni(n); // connect unused white
        rep(v, 0, n) if (!mark[v] and col[v] == 0) {
            for (auto &u : g[v])
                if (!mark[u] and col[u] == 0) {
                    uni.unite(u, v);
                }
        }
        vector tree(n, vector<int>());
        vector<int> cnt(n), can(n);
        rep(v, 0, n) {
            if (mark[v]) {
                cnt[v] = !col[v];
                can[v] = 1;
                for (auto &u : g[v]) {
                    if (mark[u]) {
                        tree[u].push_back(v);
                    } else if (col[u] == 0) {
                        int rt = uni.root(u);
                        tree[v].push_back(rt);
                        tree[rt].push_back(v);
                    }
                }
            } else if (col[v] == 0 and uni.root(v) == v) {
                cnt[v] = uni.size(v);
                can[v] = 1;
            }
        }
        rep(v, 0, n) if (!mark[v] and col[v] == 0 and uni.root(v) == v) {
            if (SZ(tree[v]) == 1) {
                cnt[tree[v][0]] += cnt[v];
                can[v] = 0;
            }
        }

        auto dfs = [&](auto &dfs, int v, int p) -> int {
            int ret = cnt[v];
            for (auto &to : tree[v])
                if (to != p) {
                    if (col[to] == 1)
                        continue;
                    if (can[to]) {
                        ret += dfs(dfs, to, v);
                    }
                }
            return ret;
        };

        rep(i, L, R) {
            auto [ty, v] = que[i];
            if (ty == 1) {
                if (col[v] == 0)
                    cnt[v]--;
                else
                    cnt[v]++;
                col[v] ^= 1;
            } else {
                int ret = dfs(dfs, v, -1);
                out.push_back(ret);
            }
        }

        L = R;
    }
    rep(i, 0, SZ(out)) print(out[i]);
    return 0;
}
accuracy: 1
time_ms: 1080
memory_kb: 14616
final_rank: 6

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

#line 2 "library/DataStructure/unionfind.hpp"

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */
#line 6 "sol.cpp"

int main() {
    int n, Q;
    read(n, Q);
    vector g(n, vector<int>());
    rep(_, 0, n - 1) {
        int x, y;
        read(x, y);
        x--, y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    using P = pair<int, int>;
    vector<P> que;
    rep(i, 0, Q) {
        int t, v;
        read(t, v);
        v--;
        que.push_back({t, v});
    }

    int SQ = max<int>(1, sqrtl(Q));
    // int SQ = Q;
    int L = 0;
    vector<int> col(n); // 0:white
    vector<int> out;
    while (L < Q) {
        int R = min(Q, L + SQ);

        vector<int> mark(n);
        rep(i, L, R) {
            mark[que[i].second] = 1;
        }
        UnionFind uni(n);
        rep(v, 0, n) if (!mark[v] and col[v] == 0) {
            for (auto &u : g[v])
                if (!mark[u] and col[u] == 0) {
                    uni.unite(u, v);
                }
        }
        vector tree(n, vector<int>());
        vector<int> cnt(n), can(n);
        rep(v, 0, n) {
            if (mark[v]) {
                cnt[v] = 1;
                can[v] = 1;
                for (auto &u : g[v]) {
                    if (mark[u]) {
                        tree[u].push_back(v);
                    } else {
                        int rt = uni.root(u);
                        tree[v].push_back(rt);
                        tree[rt].push_back(v);
                    }
                }
            } else if (col[v] == 0 and uni.root(v) == v) {
                cnt[v] = uni.size(v);
                can[v] = 1;
            }
        }
        rep(v, 0, n) if (!mark[v] and col[v] == 0 and uni.root(v) == v) {
            if (SZ(tree[v]) == 1) {
                cnt[tree[v][0]] += cnt[v];
                can[v] = 0;
            }
        }

        auto dfs = [&](auto &dfs, int v, int p) -> int {
            int ret = cnt[v];
            for (auto &to : tree[v])
                if (to != p) {
                    if (col[to] == 1)
                        continue;
                    if (can[to]) {
                        ret += dfs(dfs, to, v);
                    }
                }
            return ret;
        };

        rep(i, L, R) {
            auto [ty, v] = que[i];
            if (ty == 1) {
                if (col[v] == 0)
                    cnt[v]--;
                else
                    cnt[v]++;
                col[v] ^= 1;
            } else {
                int ret = dfs(dfs, v, -1);
                out.push_back(ret);
            }
        }

        L = R;
    }
    rep(i, 0, SZ(out)) print(out[i]);
    return 0;
}
accuracy: 0.2
time_ms: 1020
memory_kb: 14564
final_rank: 19

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

#line 2 "library/DataStructure/unionfind.hpp"

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */
#line 6 "sol.cpp"

int main() {
    int n, Q;
    read(n, Q);
    vector g(n, vector<int>());
    rep(_, 0, n - 1) {
        int x, y;
        read(x, y);
        x--, y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    using P = pair<int, int>;
    vector<P> que;
    rep(i, 0, Q) {
        int t, v;
        read(t, v);
        v--;
        que.push_back({t, v});
    }

    int SQ = max<int>(1, sqrtl(Q));
    int L = 0;
    vector<int> col(n); // 0:white
    vector<int> out;
    while (L < Q) {
        int R = min(Q, L + SQ);

        vector<int> mark(n);
        rep(i, L, R) {
            mark[que[i].second] = 1;
        }
        UnionFind uni(n);
        rep(v, 0, n) if (!mark[v] and col[v] == 0) {
            for (auto &u : g[v])
                if (!mark[u] and col[u] == 0) {
                    uni.unite(u, v);
                }
        }
        vector tree(n, vector<int>());
        vector<int> cnt(n), can(n);
        rep(v, 0, n) {
            if (mark[v]) {
                cnt[v] = 1;
                can[v] = 1;
                for (auto &u : g[v]) {
                    if (mark[u]) {
                        tree[u].push_back(v);
                    } else if (col[u] == 0) {
                        int rt = uni.root(u);
                        tree[v].push_back(rt);
                        tree[rt].push_back(v);
                    }
                }
            } else if (col[v] == 0 and uni.root(v) == v) {
                cnt[v] = uni.size(v);
                can[v] = 1;
            }
        }
        rep(v, 0, n) if (!mark[v] and col[v] == 0 and uni.root(v) == v) {
            if (SZ(tree[v]) == 1) {
                cnt[tree[v][0]] += cnt[v];
                can[v] = 0;
            }
        }

        auto dfs = [&](auto &dfs, int v, int p) -> int {
            int ret = cnt[v];
            for (auto &to : tree[v])
                if (to != p) {
                    if (col[to] == 1)
                        continue;
                    if (can[to]) {
                        ret += dfs(dfs, to, v);
                    }
                }
            return ret;
        };

        rep(i, L, R) {
            auto [ty, v] = que[i];
            if (ty == 1) {
                if (col[v] == 0)
                    cnt[v]--;
                else
                    cnt[v]++;
                col[v] ^= 1;
            } else {
                int ret = dfs(dfs, v, -1);
                out.push_back(ret);
            }
        }

        L = R;
    }
    rep(i, 0, SZ(out)) print(out[i]);
    return 0;
}
accuracy: 0.2
time_ms: 1020
memory_kb: 14372
final_rank: 18

code_snippet: #pragma GCC optimize("O3")
#ifdef t9unkubj
#include "debug.cpp"
#else
#undef _GLIBCXX_DEBUG
#define dbg(...) 199958
#endif

using namespace std;
#include<bits/stdc++.h>
using uint=unsigned;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
template<class T>using vvvc=vvc<vc<T>>;
using vi=vc<int>;
using vvi=vc<vi>;
using vvvi=vc<vvi>;
using vl=vc<ll>;
using vvl=vc<vl>;
using vvvl=vc<vvl>;
template<class T>using smpq=priority_queue<T,vector<T>,greater<T>>;
template<class T>using bipq=priority_queue<T>;
#define rep(i,n) for(ll (i)=0;i<(ll)(n);i++)
#define REP(i,j,n) for(ll (i)=(j);i<(ll)(n);i++)
#define DREP(i,n,m) for(ll (i)=(n);i>=(m);i--)
#define drep(i,n) for(ll i=((n)-1);i>=0;i--)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define is insert
#define bg begin()
#define ed end()
void scan(int&a) { cin >> a; }
void scan(ll&a) { cin >> a; }
void scan(string&a) { cin >> a; }
void scan(char&a) { cin >> a; }
void scan(uint&a) { cin >> a; }
void scan(ull&a) { cin >> a; }
void scan(bool&a) { cin >> a; }
void scan(ld&a){ cin>> a;}
template<class T> void scan(vector<T>&a) { for(auto&x:a) scan(x); }
void read() {}
template<class Head, class... Tail> void read(Head&head, Tail&... tail) { scan(head); read(tail...); }
#define INT(...) int __VA_ARGS__; read(__VA_ARGS__);
#define LL(...) ll __VA_ARGS__; read(__VA_ARGS__);
#define ULL(...) ull __VA_ARGS__; read(__VA_ARGS__);
#define STR(...) string __VA_ARGS__; read(__VA_ARGS__);
#define CHR(...) char __VA_ARGS__; read(__VA_ARGS__);
#define DBL(...) double __VA_ARGS__; read(__VA_ARGS__);
#define LD(...) ld __VA_ARGS__; read(__VA_ARGS__);
#define VC(type, name, ...) vector<type> name(__VA_ARGS__); read(name);
#define VVC(type, name, size, ...) vector<vector<type>> name(size, vector<type>(__VA_ARGS__)); read(name);
void print(int a) { cout << a; }
void print(ll a) { cout << a; }
void print(string a) { cout << a; }
void print(char a) { cout << a; }
void print(uint a) { cout << a; }
void print(bool a) { cout << a; }
void print(ull a) { cout << a; }
void print(ld a){ cout<< a; }
template<class T> void print(vector<T>a) { for(int i=0;i<(int)a.size();i++){if(i)cout<<" ";print(a[i]);}cout<<endl;}
void PRT() { cout <<endl; return ; }
template<class T> void PRT(T a) { print(a); cout <<endl; return; }
template<class Head, class... Tail> void PRT(Head head, Tail ... tail) { print(head); cout << " "; PRT(tail...); return; }
template<class T,class F>
bool chmin(T &x, F y){
    if(x>y){
        x=y;
        return true;
    }
    return false;
}
template<class T, class F>
bool chmax(T &x, F y){
    if(x<y){
        x=y;
        return true;
    }
    return false;
}
void YesNo(bool b){
    cout<<(b?"Yes":"No")<<endl;
}
void Yes(){
    cout<<"Yes"<<endl;
}
void No(){
    cout<<"No"<<endl;
}
template<class T>
int popcount(T n){
    return __builtin_popcount(n);
}
template<class T>
T sum(vc<T>&a){
    return accumulate(all(a),T(0));
}
template<class T>
T max(vc<T>&a){
    return *max_element(all(a));
}
template<class T>
T min(vc<T>&a){
    return *min_element(all(a));
}
template<class T>
void unique(vc<T>&a){
    a.erase(unique(all(a)),a.end());
}
vvi readgraph(int n,int m,int off = -1){
    vvi g(n);
    rep(i, m){
        int u,v;
        cin>>u>>v;
        u+=off,v+=off;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    return g;
}
vvi readtree(int n,int off=-1){
    return readgraph(n,n-1,off);
}
template<class T>
vc<T> presum(vc<T> &a){
    vc<T> ret(a.size()+1);
    rep(i,a.size())ret[i+1]=ret[i]+a[i];
    return ret;
}
template<class T, class F>
vc<T> &operator+=(vc<T> &a,F b){
    for (auto&v:a)v += b;
    return a;
}
template<class T, class F>
vc<T> &operator-=(vc<T>&a,F b){
    for (auto&v:a)v-=b;
    return a;
}
template<class T, class F>
vc<T> &operator*=(vc<T>&a,F b){
    for (auto&v:a)v*=b;
    return a;
}
double pass_time=0;
void solve(){
    INT(n,q);
    vvi g=readtree(n);
    vi t(q),v(q);
    rep(i,q)cin>>t[i]>>v[i];
    v-=1,t-=1;
    const int B=sqrt(q)+1;
    int si=(q+B-1)/B;
    vi col(n,1);
    for(int i=0;i<si;i++){
        int l=i*B;
        int r=min(q,l+B);
        vi ask(n);
        REP(i,l,r){
            ask[v[i]]=1;
        }
        vvi newg(n);
        vi cnt=col;//圧縮したときの頂点がもつ白頂点の数
        vi seen(n);
        auto compress=[&](int i){
            auto dfs=[&](auto&dfs,int u,int v)->int{
                seen[u]=1;
                int res=1;
                for(auto x:g[u]){
                    if(x==v)continue;
                    if(!ask[x]){
                        if(!seen[x]&&col[x])res+=dfs(dfs,x,u);
                    }else{
                        newg[i].pb(x);
                        newg[x].pb(i);
                    }
                }return res;
            };return dfs(dfs,i,-1);
        };
        vi vs;
        rep(i,n){
            if(!seen[i]&&!ask[i]&&col[i]){
                vs.pb(i);
                cnt[i]=compress(i);
            }else if(ask[i]){
                for(auto x:g[i]){
                    if(ask[x])newg[x].pb(i);
                }
            }
        }
        for(auto&x:vs)ask[x]=1;
        rep(i,n){
            if(seen[i]&&newg[i].size()==1){
                cnt[newg[i][0]]+=cnt[i];
                cnt[i]=0;   
                ask[i]=0;
            }
        }
        auto dfs=[&](auto&dfs,int u,int v)->int{
            int res=cnt[u];
            for(auto x:newg[u]){
                if(x==v)continue;
                if(ask[x]&&col[x]){
                    res+=dfs(dfs,x,u);
                }
            }
            return res;
        };
        for(int i=l;i<r;i++){
            if(t[i]==0){    
                if(col[v[i]])cnt[v[i]]--;
                else cnt[v[i]]++;
                col[v[i]]^=1;
            }else{
                PRT(dfs(dfs,v[i],-1));
            }
        }
    }
}
signed main(){
    #ifdef t9unkubj
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    cin.tie(0)->sync_with_stdio(0);
    pass_time=clock();
    int t=1;
    //cin>>t;
    while(t--)solve();
    pass_time=clock()-pass_time;
    dbg(pass_time/CLOCKS_PER_SEC);
}
accuracy: 1
time_ms: 1020
memory_kb: 13756
final_rank: 5

code_snippet: #pragma GCC optimize("O3")
#ifdef t9unkubj
#include "debug.cpp"
#else
#undef _GLIBCXX_DEBUG
#define dbg(...) 199958
#endif

using namespace std;
#include<bits/stdc++.h>
using uint=unsigned;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
template<class T>using vvvc=vvc<vc<T>>;
using vi=vc<int>;
using vvi=vc<vi>;
using vvvi=vc<vvi>;
using vl=vc<ll>;
using vvl=vc<vl>;
using vvvl=vc<vvl>;
template<class T>using smpq=priority_queue<T,vector<T>,greater<T>>;
template<class T>using bipq=priority_queue<T>;
#define rep(i,n) for(ll (i)=0;i<(ll)(n);i++)
#define REP(i,j,n) for(ll (i)=(j);i<(ll)(n);i++)
#define DREP(i,n,m) for(ll (i)=(n);i>=(m);i--)
#define drep(i,n) for(ll i=((n)-1);i>=0;i--)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define is insert
#define bg begin()
#define ed end()
void scan(int&a) { cin >> a; }
void scan(ll&a) { cin >> a; }
void scan(string&a) { cin >> a; }
void scan(char&a) { cin >> a; }
void scan(uint&a) { cin >> a; }
void scan(ull&a) { cin >> a; }
void scan(bool&a) { cin >> a; }
void scan(ld&a){ cin>> a;}
template<class T> void scan(vector<T>&a) { for(auto&x:a) scan(x); }
void read() {}
template<class Head, class... Tail> void read(Head&head, Tail&... tail) { scan(head); read(tail...); }
#define INT(...) int __VA_ARGS__; read(__VA_ARGS__);
#define LL(...) ll __VA_ARGS__; read(__VA_ARGS__);
#define ULL(...) ull __VA_ARGS__; read(__VA_ARGS__);
#define STR(...) string __VA_ARGS__; read(__VA_ARGS__);
#define CHR(...) char __VA_ARGS__; read(__VA_ARGS__);
#define DBL(...) double __VA_ARGS__; read(__VA_ARGS__);
#define LD(...) ld __VA_ARGS__; read(__VA_ARGS__);
#define VC(type, name, ...) vector<type> name(__VA_ARGS__); read(name);
#define VVC(type, name, size, ...) vector<vector<type>> name(size, vector<type>(__VA_ARGS__)); read(name);
void print(int a) { cout << a; }
void print(ll a) { cout << a; }
void print(string a) { cout << a; }
void print(char a) { cout << a; }
void print(uint a) { cout << a; }
void print(bool a) { cout << a; }
void print(ull a) { cout << a; }
void print(ld a){ cout<< a; }
template<class T> void print(vector<T>a) { for(int i=0;i<(int)a.size();i++){if(i)cout<<" ";print(a[i]);}cout<<endl;}
void PRT() { cout <<endl; return ; }
template<class T> void PRT(T a) { print(a); cout <<endl; return; }
template<class Head, class... Tail> void PRT(Head head, Tail ... tail) { print(head); cout << " "; PRT(tail...); return; }
template<class T,class F>
bool chmin(T &x, F y){
    if(x>y){
        x=y;
        return true;
    }
    return false;
}
template<class T, class F>
bool chmax(T &x, F y){
    if(x<y){
        x=y;
        return true;
    }
    return false;
}
void YesNo(bool b){
    cout<<(b?"Yes":"No")<<endl;
}
void Yes(){
    cout<<"Yes"<<endl;
}
void No(){
    cout<<"No"<<endl;
}
template<class T>
int popcount(T n){
    return __builtin_popcount(n);
}
template<class T>
T sum(vc<T>&a){
    return accumulate(all(a),T(0));
}
template<class T>
T max(vc<T>&a){
    return *max_element(all(a));
}
template<class T>
T min(vc<T>&a){
    return *min_element(all(a));
}
template<class T>
void unique(vc<T>&a){
    a.erase(unique(all(a)),a.end());
}
vvi readgraph(int n,int m,int off = -1){
    vvi g(n);
    rep(i, m){
        int u,v;
        cin>>u>>v;
        u+=off,v+=off;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    return g;
}
vvi readtree(int n,int off=-1){
    return readgraph(n,n-1,off);
}
template<class T>
vc<T> presum(vc<T> &a){
    vc<T> ret(a.size()+1);
    rep(i,a.size())ret[i+1]=ret[i]+a[i];
    return ret;
}
template<class T, class F>
vc<T> &operator+=(vc<T> &a,F b){
    for (auto&v:a)v += b;
    return a;
}
template<class T, class F>
vc<T> &operator-=(vc<T>&a,F b){
    for (auto&v:a)v-=b;
    return a;
}
template<class T, class F>
vc<T> &operator*=(vc<T>&a,F b){
    for (auto&v:a)v*=b;
    return a;
}
double pass_time=0;
void solve(){
    INT(n,q);
    vvi g=readtree(n);
    vi t(q),v(q);
    rep(i,q)cin>>t[i]>>v[i];
    v-=1,t-=1;
    const int B=sqrt(q)+1;
    int si=(q+B-1)/B;
    vi col(n,1);
    for(int i=0;i<si;i++){
        int l=i*B;
        int r=min(q,l+B);
        vi ask(n);
        REP(i,l,r){
            ask[v[i]]=1;
        }
        vvi newg(n);
        vi cnt(n);//圧縮したときの頂点がもつ白頂点の数
        vi seen(n);
        auto compress=[&](int i){
            auto dfs=[&](auto&dfs,int u,int v)->int{
                seen[u]=1;
                int res=1;
                for(auto x:g[u]){
                    if(x==v)continue;
                    if(!ask[x]){
                        if(!seen[x]&&col[x])res+=dfs(dfs,x,u);
                    }else{
                        newg[i].pb(x);
                        newg[x].pb(i);
                    }
                }return res;
            };return dfs(dfs,i,-1);
        };
        vi vs;
        rep(i,n){
            if(!seen[i]&&!ask[i]&&col[i]){
                vs.pb(i);
                cnt[i]=compress(i);
            }else if(ask[i]){
                for(auto x:g[i]){
                    if(ask[x])newg[x].pb(i);
                }
            }
        }
        for(auto&x:vs)ask[x]=1;
        rep(i,n){
            if(seen[i]&&newg[i].size()==1){
                cnt[newg[i][0]]+=cnt[i];
                cnt[i]=0;   
                seen[i]=0;
            }
        }
        auto dfs=[&](auto&dfs,int u,int v)->int{
            int res=cnt[u];
            for(auto x:g[u]){
                if(x==v)continue;
                if(ask[x]&&col[x]){
                    res+=dfs(dfs,x,u);
                }
            }
            return res;
        };
        for(int i=l;i<r;i++){
            if(t[i]==0){    
                if(col[v[i]])cnt[v[i]]--;
                else cnt[v[i]]++;
                col[v[i]]^=1;
            }else{
                PRT(dfs(dfs,v[i],-1)+1);
            }
        }
    }
}
signed main(){
    #ifdef t9unkubj
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    cin.tie(0)->sync_with_stdio(0);
    pass_time=clock();
    int t=1;
    //cin>>t;
    while(t--)solve();
    pass_time=clock()-pass_time;
    dbg(pass_time/CLOCKS_PER_SEC);
}
accuracy: 0.2
time_ms: 940
memory_kb: 13752
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,k,n) for(ll i=(ll)(k);i<(ll)(n);i++)
#define all(a) a.begin(),a.end()
#define rsort(a) {sort(all(a));reverse(all(a));}
#define dupli(a) {sort(all(a));a.erase(unique(all(a)),a.end());}
#define lb(v,k) (lower_bound(all(v),k)-v.begin())
#define fi first
#define se second
#define pb emplace_back
const ll mod=1000000007;
template<class T> bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<class T> bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){for(auto x:v)outv(x);}
template<class T> void outp(T p){cout<<'('<<p.fi<<','<<p.se<<')'<<endl;}
template<class T> void outvp(T v){for(auto p:v)cout<<'('<<p.fi<<','<<p.se<<')';cout<<endl;}
const ll inf=1001001001001001001;

class BIT{
    vi bit;
public:
    BIT(ll n):bit(n){}
    void add(ll i,ll x){
        for(int j=i;j<bit.size();j|=j+1)bit[j]+=x;
    }
    ll get(ll a){
        ll res=0;
        for(int j=a-1;j>=0;j=(j&(j+1))-1)res+=bit[j];
        return res;
    }
    ll get(ll a,ll b){
        return get(b)-get(a);
    }
    void debug(){
        vi res(bit.size());
        rep(i,bit.size())res[i]=get(i+1)-get(i);
        outv(res);
    }
};
int main(){
    ll n,q;cin>>n>>q;
    vvi g(n);rep(i,n-1){
        ll a,b;cin>>a>>b;a--;b--;
        g[a].pb(b);g[b].pb(a);
    }
    vi color(n,1);
    vi sub(n,1),par(n,-1),head(n);
    vi topo;
    function<void(ll,ll)> dfs=[&](ll i,ll p){
        par[i]=p;
        topo.pb(i);
        for(ll x:g[i])if(x!=p)dfs(x,i);
    };dfs(0,-1);
    vi rtopo=topo;reverse(all(rtopo));
    for(ll i:rtopo)for(ll x:g[i])if(x!=par[i])sub[i]+=sub[x];
    for(ll i:topo){
        ll mx=0;
        rep(j,g[i].size())if(g[i][j]!=par[i]&&chmax(mx,sub[g[i][j]]))swap(g[i][j],g[i][0]);
        rep(j,g[i].size())if(g[i][j]!=par[i]){
            if(j)head[g[i][j]]=g[i][j];
            else head[g[i][j]]=head[i];
        }
    }
    ll c=0;vi id(n);
    vector<set<ll>> S(n);
    function<void(ll,ll)> dfs2=[&](ll i,ll p){
        id[i]=c++;
        bool is_leaf=true;
        for(ll x:g[i])if(x!=p){
            dfs2(x,i);
            is_leaf=false;
        }
        if(is_leaf)S[head[i]].insert(c);
    };dfs2(0,-1);
    BIT bit(n);
    auto getans=[&](ll i){
        if(!color[i])return 0ll;
        auto itr=S[head[i]].lower_bound(id[i]);
        ll k=*itr,l;
        if(itr==S[head[i]].begin())l=id[head[i]];
        else{
            itr--;l=(*itr)+1;
        }
        return bit.get(l,k)+(k-l);
    };
    // outv(id);outv(head);
    rep(i,n)REP(j,1,g[i].size())if(g[i][j]!=par[i])bit.add(id[i],sub[g[i][j]]);
    // bit.debug();
    rep(qq,q){
        ll t,i;cin>>t>>i;i--;
        if(t==1){
            ll prev=getans(head[i]),nex;
            if(color[i])S[head[i]].insert(id[i]);
            else S[head[i]].erase(id[i]);
            color[i]=1-color[i];
            i=head[i];
            while(par[i]!=-1){
                nex=getans(i);
                ll nprev=getans(head[par[i]]);
                bit.add(id[par[i]],nex-prev);
                i=head[par[i]];
                prev=nprev;
            }
        }
        else{
            if(!color[i]){
                out(0);continue;
            }
            while(par[head[i]]!=-1){
                ll t=*S[head[i]].begin();
                if(t<=id[i])break;
                if(par[head[i]]==-1||!color[par[head[i]]])break;
                i=par[head[i]];
            }
            // out(i);
            out(getans(i));
        }
        // bit.debug();
    }
}
accuracy: 1
time_ms: 190
memory_kb: 27248
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,k,n) for(ll i=(ll)(k);i<(ll)(n);i++)
#define all(a) a.begin(),a.end()
#define rsort(a) {sort(all(a));reverse(all(a));}
#define dupli(a) {sort(all(a));a.erase(unique(all(a)),a.end());}
#define lb(v,k) (lower_bound(all(v),k)-v.begin())
#define fi first
#define se second
#define pb emplace_back
const ll mod=1000000007;
template<class T> bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<class T> bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){for(auto x:v)outv(x);}
template<class T> void outp(T p){cout<<'('<<p.fi<<','<<p.se<<')'<<endl;}
template<class T> void outvp(T v){for(auto p:v)cout<<'('<<p.fi<<','<<p.se<<')';cout<<endl;}
const ll inf=1001001001001001001;

class BIT{
    vi bit;
public:
    BIT(ll n):bit(n){}
    void add(ll i,ll x){
        for(int j=i;j<bit.size();j|=j+1)bit[j]+=x;
    }
    ll get(ll a){
        ll res=0;
        for(int j=a-1;j>=0;j=(j&(j+1))-1)res+=bit[j];
        return res;
    }
    ll get(ll a,ll b){
        return get(b)-get(a);
    }
    void debug(){
        vi res(bit.size());
        rep(i,bit.size())res[i]=get(i+1)-get(i);
        outv(res);
    }
};
int main(){
    ll n,q;cin>>n>>q;
    vvi g(n);rep(i,n-1){
        ll a,b;cin>>a>>b;a--;b--;
        g[a].pb(b);g[b].pb(a);
    }
    vi color(n,1);
    vi sub(n,1),par(n,-1),head(n);
    vi topo;
    function<void(ll,ll)> dfs=[&](ll i,ll p){
        par[i]=p;
        topo.pb(i);
        for(ll x:g[i])if(x!=p)dfs(x,i);
    };dfs(0,-1);
    vi rtopo=topo;reverse(all(rtopo));
    for(ll i:rtopo)for(ll x:g[i])if(x!=par[i])sub[i]+=sub[x];
    for(ll i:topo){
        ll mx=0;
        rep(j,g[i].size())if(g[i][j]!=par[i]&&chmax(mx,sub[g[i][j]]))swap(g[i][j],g[i][0]);
        rep(j,g[i].size())if(g[i][j]!=par[i]){
            if(j)head[g[i][j]]=g[i][j];
            else head[g[i][j]]=head[i];
        }
    }
    ll c=0;vi id(n);
    vector<set<ll>> S(n);
    function<void(ll,ll)> dfs2=[&](ll i,ll p){
        id[i]=c++;
        bool is_leaf=true;
        for(ll x:g[i])if(x!=p){
            dfs2(x,i);
            is_leaf=false;
        }
        if(is_leaf)S[head[i]].insert(c);
    };dfs2(0,-1);
    BIT bit(n);
    auto getans=[&](ll i){
        if(!color[i])return 0ll;
        auto itr=S[head[i]].lower_bound(id[i]);
        ll k=*itr,l;
        if(itr==S[head[i]].begin())l=id[head[i]];
        else{
            itr--;l=*itr;
        }
        return bit.get(l,k)+(k-l);
    };
    // outv(id);outv(head);
    rep(i,n)REP(j,1,g[i].size())if(g[i][j]!=par[i])bit.add(id[i],sub[g[i][j]]);
    // bit.debug();
    rep(qq,q){
        ll t,i;cin>>t>>i;i--;
        if(t==1){
            ll prev=getans(head[i]),nex;
            if(color[i])S[head[i]].insert(id[i]);
            else S[head[i]].erase(id[i]);
            color[i]=1-color[i];
            i=head[i];
            while(par[i]!=-1){
                nex=getans(i);
                ll nprev=getans(head[par[i]]);
                bit.add(id[par[i]],nex-prev);
                i=head[par[i]];
                prev=nprev;
            }
        }
        else{
            if(!color[i]){
                out(0);continue;
            }
            while(par[head[i]]!=-1){
                ll t=*S[head[i]].begin();
                if(t<=id[i])break;
                if(par[head[i]]==-1||!color[par[head[i]]])break;
                i=par[head[i]];
            }
            // out(i);
            out(getans(i));
        }
        // bit.debug();
    }
}
accuracy: 0.2
time_ms: 190
memory_kb: 23616
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,k,n) for(ll i=(ll)(k);i<(ll)(n);i++)
#define all(a) a.begin(),a.end()
#define rsort(a) {sort(all(a));reverse(all(a));}
#define dupli(a) {sort(all(a));a.erase(unique(all(a)),a.end());}
#define lb(v,k) (lower_bound(all(v),k)-v.begin())
#define fi first
#define se second
#define pb emplace_back
const ll mod=1000000007;
template<class T> bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<class T> bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){for(auto x:v)outv(x);}
template<class T> void outp(T p){cout<<'('<<p.fi<<','<<p.se<<')'<<endl;}
template<class T> void outvp(T v){for(auto p:v)cout<<'('<<p.fi<<','<<p.se<<')';cout<<endl;}
const ll inf=1001001001001001001;

class BIT{
    vi bit;
public:
    BIT(ll n):bit(n){}
    void add(ll i,ll x){
        for(int j=i;j<bit.size();j|=j+1)bit[j]+=x;
    }
    ll get(ll a){
        ll res=0;
        for(int j=a-1;j>=0;j=(j&(j+1))-1)res+=bit[j];
        return res;
    }
    ll get(ll a,ll b){
        return get(b)-get(a);
    }
    void debug(){
        vi res(bit.size());
        rep(i,bit.size())res[i]=get(i+1)-get(i);
        outv(res);
    }
};
int main(){
    ll n,q;cin>>n>>q;
    vvi g(n);rep(i,n-1){
        ll a,b;cin>>a>>b;a--;b--;
        g[a].pb(b);g[b].pb(a);
    }
    vi color(n,1);
    vi sub(n,1),par(n,-1),head(n);
    vi topo;
    function<void(ll,ll)> dfs=[&](ll i,ll p){
        par[i]=p;
        topo.pb(i);
        for(ll x:g[i])if(x!=p)dfs(x,i);
    };dfs(0,-1);
    vi rtopo=topo;reverse(all(rtopo));
    for(ll i:rtopo)for(ll x:g[i])if(x!=par[i])sub[i]+=sub[x];
    for(ll i:topo){
        ll mx=0;
        rep(j,g[i].size())if(g[i][j]!=par[i]&&chmax(mx,sub[g[i][j]]))swap(g[i][j],g[i][0]);
        rep(j,g[i].size())if(g[i][j]!=par[i]){
            if(j)head[g[i][j]]=g[i][j];
            else head[g[i][j]]=head[i];
        }
    }
    ll c=0;vi id(n);
    vector<set<ll>> S(n);
    function<void(ll,ll)> dfs2=[&](ll i,ll p){
        id[i]=c++;
        bool is_leaf=true;
        for(ll x:g[i])if(x!=p){
            dfs2(x,i);
            is_leaf=false;
        }
        if(is_leaf)S[head[i]].insert(c);
    };dfs2(0,-1);
    BIT bit(n);
    auto getans=[&](ll i){
        ll k=*S[head[i]].lower_bound(id[i]);
        // out(k);
        return bit.get(id[i],k)+(k-id[i]);
    };
    // outv(id);outv(head);
    rep(i,n)REP(j,1,g[i].size())if(g[i][j]!=par[i])bit.add(id[i],sub[g[i][j]]);
    // bit.debug();
    rep(qq,q){
        ll t,i;cin>>t>>i;i--;
        if(t==1){
            ll prev=getans(head[i]),nex;
            if(color[i])S[head[i]].insert(id[i]);
            else S[head[i]].erase(id[i]);
            color[i]=1-color[i];
            i=head[i];
            while(par[i]!=-1){
                nex=getans(i);
                ll nprev=getans(head[par[i]]);
                bit.add(id[par[i]],nex-prev);
                i=head[par[i]];
                prev=nprev;
            }
        }
        else{
            if(!color[i]){
                out(0);continue;
            }
            while(par[head[i]]!=-1){
                ll t=*S[head[i]].begin();
                if(t<=id[i])break;
                if(par[head[i]]==-1||!color[par[head[i]]])break;
                i=par[head[i]];
            }
            // out(i);
            out(getans(i));
        }
        // bit.debug();
    }
}
accuracy: 0.2
time_ms: 190
memory_kb: 23556
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        vec<int> v;
        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                v.push_back(i);
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        for(auto& x:v) use[x] = true;
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(col[A[i]]) cnt[A[i]]--;
                else cnt[A[i]]++;
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 1
time_ms: 660
memory_kb: 13948
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
//                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        /*
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }
        */

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            assert(col[cur]);
            for(auto& to:tree[cur]) if(to!=par && col[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(!col[A[i]]) cnt[A[i]] = 1;
                col[A[i]] ^= 1;
            }else{
                assert(col[A[i]]);
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 1
time_ms: 620
memory_kb: 13892
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
//                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        /*
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }
        */

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            assert(col[cur]);
            for(auto& to:tree[cur]) if(to!=par && col[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                col[A[i]] ^= 1;
            }else{
                assert(col[A[i]]);
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 590
memory_kb: 13744
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
//                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        /*
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }
        */

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(cnt[A[i]]==0) cnt[A[i]] = 1;
                else cnt[A[i]] = 0;
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 1
time_ms: 610
memory_kb: 13860
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
//                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        /*
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }
        */

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 570
memory_kb: 13676
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        /*
        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }
        */

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 570
memory_kb: 13888
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        rep(i,N) if(vis[i] && tree[i].size()==1){
//            use[i] = false;
//            cnt[tree[i][0]] += cnt[i];
//            cnt[i] = 0;
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 640
memory_kb: 13996
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            cnt[i] = 0;
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 620
memory_kb: 13788
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            assert(use[tree[i][0]] && !vis[tree[i][0]]);
            cnt[tree[i][0]] += cnt[i];
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(!col[A[i]]) cnt[A[i]]++;
                else cnt[A[i]]--;
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 620
memory_kb: 13860
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        rep(i,N) if(vis[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(!col[A[i]]) cnt[A[i]]++;
                else cnt[A[i]]--;
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 640
memory_kb: 13956
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

constexpr int si = 500;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,Q;
    cin >> N >> Q;
    vvec<int> g(N);
    rep(i,N-1){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vec<int> col(N,1);
    vec<int> ans;
    int K = (Q+si-1)/si;
    vvec<int> T(K),A(K);
    rep(i,Q){
        int t,a;
        cin >> t >> a;
        a--;
        int k = i/si;
        T[k].push_back(t);
        A[k].push_back(a);
    }
    auto solve = [&](vec<int>& T,vec<int>& A){
        int n = T.size();
        vec<int> use(N);
        vvec<int> tree(N);
        rep(i,n) use[A[i]] = true;
        vec<int> cnt = col;
        vec<int> vis(N);

        auto compress = [&](auto&& self,int cur,int par,int s)->int{
            vis[cur] = 1;
            int c = 1;
            for(auto& to:g[cur]) if(to!=par){
                if(!use[to]){
                    if(!vis[to] && col[to]) c += self(self,to,cur,s);
                }else{
                    tree[s].push_back(to);
                    tree[to].push_back(s);
                }
            }
            return c;
        };

        rep(i,N){
            if(!use[i] && !vis[i] && col[i]){
                cnt[i] = compress(compress,i,-1,i);
                use[i] = true;
            }
            else if(use[i]){
                for(auto& to:g[i]) if(use[to]) tree[i].push_back(to);
            }
        }

        rep(i,N) if(use[i] && tree[i].size()==1){
            use[i] = false;
            cnt[tree[i][0]] += cnt[i];
            tree[i].clear();
        }

        auto dfs = [&](auto&& self,int cur,int par)->int{
            int c = cnt[cur];
            for(auto& to:tree[cur]) if(to!=par && col[to] && use[to]){
                c += self(self,to,cur);
            }
            return c;
        };

        rep(i,n){
            if(T[i]==1){
                if(!col[A[i]]) cnt[A[i]]++;
                else cnt[A[i]]--;
                col[A[i]] ^= 1;
            }else{
                ans.push_back(dfs(dfs,A[i],-1));
            }
        }
    };

    rep(i,K) solve(T[i],A[i]);
    for(auto& x:ans) cout << x << "\n";
}
accuracy: 0.2
time_ms: 610
memory_kb: 13876
final_rank: 10