#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
using namespace std;
using ll = long long int;
const int inf = 2e9;
struct DSUrb {
  vector<int> e;
  void init(int n) { e = vector<int>(n, -1); }
  int get(int x) { return e[x] < 0 ? x : get(e[x]); }
  bool sameSet(int a, int b) { return get(a) == get(b); }
  int size(int x) { return -e[get(x)]; }
  vector<array<int, 4>> states;
  bool unite(int x, int y) {
    x = get(x), y = get(y);
    if (x == y) {
      states.push_back({inf, inf, inf, inf});
      return 0;
    }
    if (e[x] > e[y]) swap(x, y);
    states.push_back({x, y, e[x], e[y]});
    e[x] += e[y];
    e[y] = x;
    return 1;
  }
  void rollback() {
    auto a = states.back();
    states.pop_back();
    if (a[0] != inf) e[a[0]] = a[2], e[a[1]] = a[3];
  }
};
vector<vector<array<int, 2>>> qu(500005);
vector<int> ans;
template <int SZ>
struct DynaCon {
  DSUrb D;
  vector<pair<int, int>> seg[2 * SZ];
  void upd(int l, int r, pair<int, int> p) {
    for (l += SZ, r += SZ + 1; l < r; l /= 2, r /= 2) {
      if (l & 1) seg[l++].push_back(p);
      if (r & 1) seg[--r].push_back(p);
    }
  }
  void process(int ind) {
    for (auto &t : seg[ind]) D.unite(t.first, t.second);
    if (ind >= SZ) {
      for (auto [id, x] : qu[ind - SZ]) ans[id] = D.size(x);
    } else
      process(2 * ind), process(2 * ind + 1);
    for (auto i = 0u; i < seg[ind].size(); ++i) D.rollback();
  }
};
DynaCon<500005> DC;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  int n, q, k;
  cin >> n >> q >> k;
  DC.D.init(n + 1);
  int day = 0;
  qu.push_back({});
  int qryid = 0;
  vector<array<int, 5>> edges;
  vector<int> last(q + k + 3, q + 2);
  for (int i = 0; i < q; ++i) {
    int type;
    cin >> type;
    if (type == 1) {
      int x, y;
      cin >> x >> y;
      edges.push_back({x, y, i, day});
    } else if (type == 2) {
      int u;
      cin >> u;
      qu[i].push_back({qryid++, u});
    } else {
      last[day] = i;
      ++day, qu.push_back({});
    }
  }
  for (auto &ed : edges) {
    ed[3] = last[ed[3] + k - 1];
    DC.upd(ed[2], ed[3], {ed[0], ed[1]});
  }
  ans.resize(qryid);
  DC.process(1);
  for (auto y : ans) cout << y << ' ';
  cout << '\n';
}
