#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;
}
