#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
vector<int> e[N << 2];
int n, f[N << 2], sz[N << 2];
int find(int x) { return x == f[x] ? x : find(f[x]); }
stack<pair<int, int> > S;
void merge(int x, int y) {
  if (x == y) return;
  if (sz[x] > sz[y]) swap(x, y);
  S.push(make_pair(x, sz[x]));
  f[x] = y;
  sz[y] += sz[x];
}
int opt[N], x[N], y[N], d[N];
void query(int p, int l, int r) {
  int num = S.size(), flag = 0;
  for (int i = 0; i < e[p].size(); ++i) {
    int u = find(x[e[p][i]]), v = find(y[e[p][i]]);
    if (u != v) merge(u, v);
  }
  if (l == r) {
    if (opt[l] == 2) cout << sz[find(x[l])] << "\n";
  } else {
    int mid = (l + r) >> 1;
    query(p << 1, l, mid), query(p << 1 | 1, mid + 1, r);
  }
  while (S.size() > num) {
    sz[f[S.top().first]] -= S.top().second;
    f[S.top().first] = S.top().first;
    S.pop();
  }
}
void upt(int p, int l, int r, int ql, int qr, int id) {
  if (ql <= l && r <= qr) return e[p].push_back(id), void(0);
  int mid = (l + r) >> 1;
  if (ql <= mid) upt(p << 1, l, mid, ql, qr, id);
  if (mid + 1 <= qr) upt(p << 1 | 1, mid + 1, r, ql, qr, id);
}
int tot, id[N];
int main() {
  int n, q, k, day = 1;
  cin >> n >> q >> k;
  for (int i = 1; i <= n; ++i) f[i] = i, sz[i] = 1;
  for (int i = 1; i <= q; ++i) {
    cin >> opt[i];
    if (opt[i] == 1) cin >> x[i] >> y[i], d[i] = day;
    if (opt[i] == 2) cin >> x[i];
    if (opt[i] == 3) ++day, id[day] = i;
  }
  for (int i = 1; i <= q; ++i)
    if (opt[i] == 1) upt(1, 1, q, i, d[i] + k <= day ? id[d[i] + k] : q, i);
  query(1, 1, q);
  return 0;
}
