#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define eps 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LLINF 1LL<<62 #define speed std::ios::sync_with_stdio(false); typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair pll; typedef complex point; typedef pair pii; typedef pair piii; typedef vector vi; #define CLR(x,y) memset(x,y,sizeof(x)) #define CPY(x,y) memcpy(x,y,sizeof(x)) #define clr(a,x,size) memset(a,x,sizeof(a[0])*(size)) #define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define lowbit(x) (x&(-x)) #define MID(x,y) (x+((y-x)>>1)) #define getidx(l,r) (l+r | l!=r) #define ls getidx(l,mid) #define rs getidx(mid+1,r) #define lson l,mid #define rson mid+1,r #define root 1,n template inline bool read(T &n) { T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true; } template inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48); } const int MAXN=30005; const int MAXM=100005; const int MAXQ=100005; int t,n,m,q; struct edge { int a,b; edge(){} edge(int aa,int bb):a(aa),b(bb){} bool operator < (const edge &o) const { if(a == o.a) { return b < o.b; } return a < o.a; } }; multiset S; multiset V; struct Ans { int kind; int a; int b; int val; }ans[MAXQ]; struct Edge { int u,v,w; int next; }e[MAXN<<1]; int head[MAXN],tot; int siz[MAXN],p[MAXN],son[MAXN],dep[MAXN]; int dfn[MAXN],top[MAXN],tim; int sum[MAXN<<1],la[MAXN<<1]; int bingchafa[MAXN]; int getfather(int x) { if(bingchafa[x] == x) return x; return bingchafa[x] = getfather(bingchafa[x]); } void init() { CLR(head,-1);CLR(sum,0); tot=tim=0; for(int i=1;i<=n;i++) bingchafa[i] = i; S.clear(); V.clear(); } void addedge(int u,int v,int w) { e[tot].u=u;e[tot].v=v;e[tot].w=w; e[tot].next=head[u];head[u]=tot++; } void dfs(int u,int fa=0,int depth=0) { siz[u]=1;son[u]=-1; p[u]=fa;dep[u]=depth; for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(v==p[u]) continue; dfs(v,u,depth+1); siz[u]+=siz[v]; if(son[u]==-1 || siz[v]>siz[son[u]]) son[u]=v; } } void getid(int u,int fa) { dfn[u]=++tim;top[u]=fa; if(son[u]!=-1) getid(son[u],fa); for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(v==p[u] || v==son[u]) continue; getid(v,v); } } void pushup(int l,int r) { int idx=getidx(l,r),mid=MID(l,r); sum[idx]=0; if(!la[ls]) sum[idx]+=sum[ls]; if(!la[rs]) sum[idx]+=sum[rs]; } void pushdown(int l,int r) { int idx=getidx(l,r),mid=MID(l,r); if(!la[idx]) return; la[ls]=la[idx]; la[rs]=la[idx]; } void build(int l,int r) { int idx=getidx(l,r); la[idx]=0; if(l==r) { sum[idx]=1; return; } int mid=MID(l,r); build(l,mid); build(mid+1,r); pushup(l,r); } void update2(int l,int r,int L,int R) { int idx=getidx(l,r); if(L==l && r==R) { la[idx]=1; sum[idx]=0; return; } pushdown(l,r); int mid=MID(l,r); if(R<=mid) update2(l,mid,L,R); else if(L>mid) update2(mid+1,r,L,R); else update2(l,mid,L,mid),update2(mid+1,r,mid+1,R); pushup(l,r); } int query(int l,int r,int L,int R) { int idx=getidx(l,r); if(la[idx]) return 0; if(L==l && r==R) { return sum[idx]; } int mid=MID(l,r); if(R<=mid) return query(lson,L,R); if(L>mid) return query(rson,L,R); return query(lson,L,mid)+query(rson,mid+1,R); } void change(int u,int v) { while(top[u]!=top[v]) { if(dep[top[u]]>dep[top[v]]) swap(u,v); update2(1,tim,dfn[top[v]],dfn[v]); v=p[top[v]]; } if(u==v) return; if(dep[u]>dep[v]) swap(u,v); update2(1,tim,dfn[son[u]],dfn[v]); } int query(int u,int v) { int ans=0; while(top[u]!=top[v]) { if(dep[top[u]]>dep[top[v]]) swap(u,v); ans+=query(1,tim,dfn[top[v]],dfn[v]); v=p[top[v]]; } if(u==v) return ans; if(dep[u]>dep[v]) swap(u,v); ans+=query(1,tim,dfn[u]+1,dfn[v]); return ans; } int main() { scanf("%d",&t); for(int cas = 1;cas <= t;cas++) { scanf("%d%d%d",&n,&m,&q); init(); for(int i=1;i<=m;i++) { edge tmp; scanf("%d%d",&tmp.a,&tmp.b); if(tmp.a > tmp.b) swap(tmp.a,tmp.b); S.insert(tmp); } for(int i=1;i<=q;i++) { scanf("%d%d%d",&ans[i].kind,&ans[i].a,&ans[i].b); if(ans[i].a > ans[i].b) swap(ans[i].a,ans[i].b); if(ans[i].kind == 1) { multiset::iterator Pos = S.find(edge(ans[i].a,ans[i].b)); S.erase(Pos); } } for(multiset::iterator It = S.begin();It != S.end();++It) { if(getfather(It->a) != getfather(It->b)) { bingchafa[getfather(It->a)] = getfather(It->b); V.insert(*It); } } for(multiset::iterator It = V.begin();It != V.end();++It) { addedge(It->a,It->b,1); addedge(It->b,It->a,1); } dfs(1);getid(1,1); build(1,tim); for(multiset::iterator It = S.begin();It != S.end();++It) if(V.find(*It) == V.end()) { change(It->a,It->b); } for(int i=q;i>=1;i--) { if(ans[i].kind == 1) change(ans[i].a,ans[i].b); else if(ans[i].kind == 2) ans[i].val = query(ans[i].a,ans[i].b); } printf("Case #%d:\n",cas); for(int i=1;i<=q;i++) if(ans[i].kind == 2) printf("%d\n",ans[i].val); } return 0; }