#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)1e6 + 100;
const int mod = (int)1e9 + 7;
const double pi = acos(-1.0);
int n, q, pos[maxn], added[maxn], cnt, num, u, v;
map<pair<int, int>, int> id;
char type[maxn];
pair<int, int> a[maxn];
struct DSU {
  int par[maxn], sz[maxn];
  DSU() {}
  int get(int v) {
    while (v != par[v]) v = par[v];
    return v;
  }
  int getsz(int v) { return sz[get(v)]; }
  inline void unite(int u, int v) {
    u = get(u), v = get(v);
    if (u != v) {
      cnt--;
      if (sz[u] > sz[v]) swap(u, v);
      par[u] = v;
      added[++num] = u;
      sz[v] += sz[u];
    }
  }
  inline void prev() {
    int lst = added[num];
    sz[par[lst]] -= sz[lst];
    par[lst] = lst;
    cnt++;
    num--;
  }
};
DSU dsu;
vector<int> ans;
int k;
bool ok[maxn];
int node[maxn];
void build(int l, int r) {
  if (r < l) return;
  if (l == r) {
    if (type[l] == '?') ans.push_back(dsu.getsz(node[l]));
    return;
  }
  int cur = num, mid = (l + r) >> 1;
  for (int i = (mid + 1); i <= (r); ++i) {
    if (type[i] == '-' && pos[i] < l) dsu.unite(a[i].first, a[i].second);
  }
  build(l, mid);
  while (num > cur) dsu.prev();
  for (int i = (l); i <= (mid); ++i) {
    if (type[i] == '+' && pos[i] > r) {
      dsu.unite(a[i].first, a[i].second);
    }
  }
  build(mid + 1, r);
  while (num > cur) dsu.prev();
}
int day, i;
queue<pair<pair<int, int>, pair<int, int> > > qq;
bool was[maxn];
map<pair<int, int>, int> last, deleted;
int main() {
  scanf("%d%d%d", &n, &q, &k);
  for (int ii = 1; ii <= q; ii++) {
    int tp;
    scanf("%d", &tp);
    if (tp == 1) {
      scanf("%d%d", &u, &v);
      if (u > v) swap(u, v);
      if (last[{u, v}] != 0 && !deleted[{u, v}]) {
        was[last[{u, v}]] = 1;
        type[++i] = '-';
        a[i] = make_pair(u, v);
        pos[i] = id[a[i]];
        pos[pos[i]] = i;
        id.erase(a[i]);
      }
      type[++i] = '+';
      a[i] = make_pair(u, v);
      id[a[i]] = i;
      last[a[i]] = i;
      qq.push({a[i], {day, i}});
    } else if (tp == 2) {
      type[++i] = '?';
      scanf("%d", &v);
      node[i] = v;
    } else {
      day++;
      while (((int)(qq).size()) && qq.front().second.first < day - k + 1) {
        int u = qq.front().first.first, v = qq.front().first.second;
        if (!was[qq.front().second.second]) {
          type[++i] = '-';
          a[i] = make_pair(u, v);
          deleted[{u, v}] = 1;
          pos[i] = id[a[i]];
          pos[pos[i]] = i;
          id.erase(a[i]);
        }
        qq.pop();
      }
    }
  }
  while (!id.empty()) {
    auto to = id.begin();
    pos[++i] = to->second;
    pos[pos[i]] = i;
    a[i] = (to->first);
    type[i] = '-';
    id.erase(a[i]);
  }
  q = i;
  for (int i = (1); i <= (n); ++i) dsu.par[i] = i, dsu.sz[i] = 1;
  build(1, q);
  for (auto x : ans) printf("%d\n", x);
}
