#include <bits/stdc++.h>   using namespace std;   int n, q, k;   struct node {     int c[2], fa, siz, tot;     int val, id, mid, mv;     bool rev;     node() { rev = false; }   } t[600010];   void maintain(int rt) {     t[rt].siz = t[t[rt].c[0]].siz + t[t[rt].c[1]].siz + t[rt].tot;     t[rt].mid = t[rt].id;     t[rt].mv = t[rt].val;     if (t[rt].c[0] && t[t[rt].c[0]].mv < t[rt].mv)       t[rt].mv = t[t[rt].c[0]].mv, t[rt].mid = t[t[rt].c[0]].mid;     if (t[rt].c[1] && t[t[rt].c[1]].mv < t[rt].mv)       t[rt].mv = t[t[rt].c[1]].mv, t[rt].mid = t[t[rt].c[1]].mid;     return;   }   bool isroot(int k) { return (t[t[k].fa].c[0] != k && t[t[k].fa].c[1] != k); }   void connect(int k, int f, int p) {     t[k].fa = f;     t[f].c[p] = k;     return;   }   int id(int k) { return (t[t[k].fa].c[0] == k ? 0 : 1); }   void rotate(int x) {     int y = t[x].fa, z = t[y].fa, fx = id(x), fy = id(y);     if (!isroot(y)) t[z].c[fy] = x;     t[x].fa = z;     connect(t[x].c[fx ^ 1], y, fx);     connect(y, x, fx ^ 1);     maintain(y);     maintain(x);     return;   }   void pushdown(int rt) {     if (!t[rt].rev) return;     t[t[rt].c[0]].rev ^= 1;     t[t[rt].c[1]].rev ^= 1;     swap(t[rt].c[0], t[rt].c[1]);     t[rt].rev = false;     return;   }   stack<int> s;   void splay(int x) {     s.push(x);     for (int i = x; !isroot(i); i = t[i].fa) s.push(t[i].fa);     while (!s.empty()) {       pushdown(s.top());       s.pop();     }     while (!isroot(x)) {       int y = t[x].fa;       if (isroot(y)) {         rotate(x);         break;       }       if (id(x) == id(y)) {         rotate(y);         rotate(x);       } else {         rotate(x);         rotate(x);       }     }     return;   }   void access(int k) {     for (int i = 0; k; i = k, k = t[k].fa) {       splay(k);       t[k].tot += t[t[k].c[1]].siz;       t[k].tot -= t[i].siz;       t[k].c[1] = i;       maintain(k);     }     return;   }   void makeroot(int k) {     access(k);     splay(k);     t[k].rev ^= 1;     return;   }   void link(int x, int y) {     makeroot(x);     makeroot(y);     t[x].fa = y;     t[y].tot += t[x].siz;     maintain(y);     return;   }   void cut(int x, int y) {     makeroot(x);     access(y);     splay(x);     t[x].c[1] = 0;     t[y].fa = 0;     t[x].siz -= t[y].siz;     maintain(x);     return;   }   struct edge {     int u, v, t;     bool del;   } es[600010];   int en = 0;   int main() {     scanf( %d%d%d , &n, &q, &k);     int ecur = 0;     int cur = 1;     int ty, x, y;     for (int i = 1; i <= n; ++i)       t[i].siz = t[i].tot = 1, t[i].val = t[i].mv = 0x3f3f3f3f;     for (int i = 1; i <= q; ++i) {       scanf( %d , &ty);       if (ty == 1) {         scanf( %d%d , &x, &y);         es[++en] = (edge){x, y, cur, false};         makeroot(x);         access(y);         splay(x);         int v = y;         while (t[v].fa) v = t[v].fa;         if (v == x) {           splay(y);           int cute = t[y].mid;           cut(es[cute].u, cute + n);           cut(es[cute].v, cute + n);           es[cute].del = true;         }         t[en + n].siz = 1;         t[en + n].val = cur;         t[en + n].id = en;         t[en + n].mv = cur;         t[en + n].mid = en;         link(x, en + n);         link(y, en + n);       }       if (ty == 2) {         scanf( %d , &x);         makeroot(x);         printf( %d n , t[x].siz);       }       if (ty == 3) {         ++cur;         while (ecur < en && es[ecur + 1].t <= cur - k) {           ++ecur;           if (!es[ecur].del) {             cut(es[ecur].u, ecur + n);             cut(es[ecur].v, ecur + n);           }         }       }     }     return 0;   }