// compile: make data
// run: time ./data < data.in > data.out
#include <bits/stdc++.h>
using namespace std;
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x),__VA_ARGS__})
#define cmax(x,...) x=max({(x),__VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
// #define INF (int)(1152921504606846976)
#define INF (int)(0x3f3f3f3f)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
// #define int long long
#define uint unsigned long long
#define MAXN 200010
struct lct {
struct node {
node *ch[2], *parent;
int inv, minv, minp, val;
};
vector<node> vertex;
vector<vector<int>> ch;
int n;
lct(int N) {vertex.resize(n = N); }
int ind(node *x) {return x - &vertex[0]; }
int isroot(node *x) {return x->parent ? (x->parent->ch[0] != x && x->parent->ch[1] != x) : 1; }
void pushdown(node *x){
if (x->inv) {
if (x->ch[0]) x->ch[0]->inv ^= 1;
if (x->ch[1]) x->ch[1]->inv ^= 1;
swap(x->ch[0], x->ch[1]);
x->inv = 0;
}
}
void pushup(node *x) {
int lc = x->ch[0] ? x->ch[0]->minv : INF;
int rc = x->ch[1] ? x->ch[1]->minv : INF;
x->minv = x->val, x->minp = ind(x);
if (lc < x->minv) x->minv = lc, x->minp = x->ch[0]->minp;
if (rc < x->minv) x->minv = rc, x->minp = x->ch[1]->minp;
}
void rotate(node *x) {
node *y = x->parent, *z = y->parent;
int t = y->ch[1] == x;
if (!isroot(y)) z->ch[z->ch[1]==y] = x;
y->ch[t] = x->ch[!t];
if (x->ch[!t]) x->ch[!t]->parent = y;
x->ch[!t] = y, y->parent = x, x->parent = z;
pushup(y);
}
void splay(node *x) {
stack<node*> st; st.push(x);
for (node *i = x; !isroot(i); i = i->parent) st.push(i->parent);
while (!st.empty()) pushdown(st.top()), st.pop();
for (node *y = x->parent; y && !isroot(x); y = x->parent) {
if (!isroot(y)) rotate(((y->parent->ch[0]==y) ^ (y->parent->ch[0]==x)) ? x : y);
rotate(x);
}
pushup(x);
}
node *access(node *x){
node *t = nullptr;
for (; x; t = x, x = x->parent) splay(x), x->ch[1] = t;
return t;
}
int find(int u){
node *x = &vertex[u];
access(x), splay(x);
node *now = x;
while (now->ch[0]) now = now->ch[0];
return ind(now);
}
void makeroot(int u) {
node *x = &vertex[u];
access(x), splay(x);
x->inv ^= 1;
}
void link(int u, int v) {
makeroot(u);
if(find(u) != find(v)) vertex[u].parent = &vertex[v];
}
void cut(int u, int v){
makeroot(u);
access(&vertex[v]), splay(&vertex[v]);
if (vertex[u].parent != &vertex[v] || vertex[u].ch[1]) return;
vertex[u].parent = vertex[v].ch[0] = nullptr;
}
void single_modify(int u, int x) {
vertex[u].val = x;
splay(&vertex[u]);
}
node *interval(int u, int v) {
makeroot(u);
access(&vertex[v]), splay(&vertex[v]);
return &vertex[v];
}
node *range_query(int x, int y) {
return interval(x, y);
}
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, m, T; cin >> n >> m >> T;
int cnt = 0;
lct t(n+m+T);
vector<pair<int, int>> adj;
map<pair<int, int>, int> mp;
auto add = [&](int u, int v, int clock) {
if (u > v) swap(u, v);
int mid = n + cnt++;
adj.push_back({u, v});
mp[{u, v}] = mid;
t.vertex[mid].val = clock;
t.link(u, mid), t.link(mid, v);
};
struct op { int u, v, ins, del; };
vector<op> ops;
map<pair<int, int>, int> tmp;
for (int i = 0; i < m; ++i) {
int u, v; cin >> u >> v; --u, --v;
if (u > v) swap(u, v);
ops.push_back({u, v, 0, T+1}), tmp[{u, v}] = i;
}
for (int i = 0, idx = m; i < T; ++i) {
int opt, u, v; cin >> opt >> u >> v; --u, --v;
if (u > v) swap(u, v);
if (opt == 1) ops.push_back({u, v, i+1, T+1}), tmp[{u, v}] = idx++;
else ops[tmp[{u, v}]].del = i+1;
}
multiset<int, greater<int>> edges;
rep(i, 0, n) t.vertex[i].val = T+2;
for (int clock = 0, i = 0; clock <= T; ++clock) {
for (; i < sz(ops) && ops[i].ins <= clock; ++i) {
int u = ops[i].u, v = ops[i].v, del = ops[i].del;
if (t.find(u) != t.find(v)) add(u, v, del), edges.insert(del);
else {
auto *x = t.interval(u, v);
if (x->minv >= del) continue;
int mid = x->minp;
auto [l, r] = adj[mid-n];
auto it = edges.find(t.vertex[mid].val);
if (it != edges.end()) edges.erase(it);
t.cut(l, mid), t.cut(mid, r);
edges.insert(del);
add(u, v, del);
}
}
auto it = edges.lower_bound(clock);
edges.erase(it, edges.end());
printf("%d ", n - sz(edges));
}
printf("\n");
return 0;
}
No Comments