#include <bits/stdc++.h>
using namespace std;
const int mxn = 5e5 + 5;
int n, q, k;
struct QR {
  int t, a, b;
} qq[mxn];
struct DSU {
  int fa[mxn], sz[mxn];
  DSU() {
    for (int i = 0; i < (int)(mxn); ++i) fa[i] = i, sz[i] = 1;
  }
  int find(int x) { return x == fa[x] ? x : find(fa[x]); }
  vector<pair<int, int> > LINK;
  void merge(int x, int y) {
    x = find(x), y = find(y);
    if (x != y) {
      if (sz[x] < sz[y]) swap(x, y);
      fa[y] = x;
      sz[x] += sz[y];
      LINK.push_back(make_pair(x, y));
    } else {
      LINK.push_back(make_pair(-1, -1));
    }
  }
  void backtrack() {
    assert(!LINK.empty());
    int u = LINK[LINK.size() - 1].first;
    int v = LINK[LINK.size() - 1].second;
    if (u != -1) {
      fa[v] = v;
      sz[u] -= sz[v];
    }
    LINK.resize(LINK.size() - 1);
  }
} dsu;
struct SEG {
  static const int mxn = 1 << 19;
  vector<pair<int, int> > qr[mxn << 1];
  void upd(int l, int r, pair<int, int> p) {
    for (l += mxn, r += mxn; l < r; l >>= 1, r >>= 1) {
      if (l & 1) qr[l++].push_back(p);
      if (r & 1) qr[--r].push_back(p);
    }
  }
  void solve(int i, int l, int r) {
    for (int j = 0; j < (int)(qr[i].size()); ++j) {
      int x = qr[i][j].first;
      int y = qr[i][j].second;
      dsu.merge(x, y);
    }
    if (l + 1 == r) {
      if (l < q && qq[l].t == 2) printf("%d\n", dsu.sz[dsu.find(qq[l].a)]);
    } else {
      int m = (l + r) >> 1;
      solve(i << 1, l, m);
      solve(i << 1 | 1, m, r);
    }
    for (int j = 0; j < (int)(qr[i].size()); ++j) {
      dsu.backtrack();
    }
  }
} seg;
int days[mxn];
bool del[mxn];
int main() {
  scanf("%d %d %d", &n, &q, &k);
  int d = 0;
  int j = 0;
  for (int i = 0; i < (int)(q); ++i) {
    scanf("%d", &qq[i].t);
    days[i] = d;
    if (qq[i].t == 1) {
      scanf("%d %d", &qq[i].a, &qq[i].b);
      --qq[i].a;
      --qq[i].b;
    } else if (qq[i].t == 2) {
      scanf("%d", &qq[i].a);
      --qq[i].a;
    } else {
      ++d;
      ++days[i];
      while (days[j] <= d - k) {
        if (qq[j].t == 1) {
          seg.upd(j, i, make_pair(qq[j].a, qq[j].b));
          del[j] = 1;
        }
        ++j;
      }
    }
  }
  for (int i = 0; i < (int)(q); ++i) {
    if (!del[i] && qq[i].t == 1) {
      seg.upd(i, q, make_pair(qq[i].a, qq[i].b));
    }
  }
  seg.solve(1, 0, SEG::mxn);
  return 0;
}
