#include<bits/stdc++.h>
using namespace std;
#define int long long
#define debug cout<<-1<<endl
const int maxn=3e4+5;
int n,m,Q;
int aa[maxn],bb[maxn],opt[maxn],ll[maxn],rr[maxn];
map<pair<int,int>,int> op;
vector<int>q[maxn];
int ans[maxn];
int unfa[maxn];
int rest1[maxn],rest2[maxn];
int siz[maxn],dep[maxn],son[maxn],top[maxn],id[maxn],fa[maxn];
int a[maxn],ca[4*maxn],sum[4*maxn];
int cnt=0,tem=0;
int find(int a){
if(unfa[a]==a){
return a;
}
unfa[a]=find(unfa[a]);
return unfa[a];
}
void unio(int a,int b){
if(a!=b){
unfa[a]=b;
}
}
void dfs1(int p,int last){
dep[p]=dep[fa[p]]+1;
siz[p]=1;
for(int i=0;i<q[p].size();i++){
int v=q[p][i];
if(v!=fa[p]&&op[make_pair(p,v)]!=1){
fa[v]=p;
dfs1(v,p);
siz[p]+=siz[v];
if(siz[son[p]]<siz[v]){
son[p]=v;
}
}
}
}
void dfs2(int p,int tp){
id[p]=++tem;top[p]=tp;
if(son[p]){
dfs2(son[p],tp);
}
for(int i=0;i<q[p].size();i++){
int v=q[p][i];
if(v!=fa[p]&&v!=son[p]&&op[make_pair(p,v)]!=1){
dfs2(v,v);
}
}
}
inline int ls(int a){
return 2*a;
}
inline int rs(int a){
return 2*a+1;
}
inline void pushup(int a){
sum[a]=sum[ls(a)]+sum[rs(a)];
}
void build(int l,int r,int p){
ca[p]=-1;
if(l==r){
sum[p]=1;
return;
}
int mid=(l+r)/2;
build(l,mid,ls(p));
build(mid+1,r,rs(p));
pushup(p);
return;
}
inline void f(int l,int r,int p,int k){
if(k==0){
ca[p]=0;
sum[p]=0;
}
}
void pushdown(int l,int r,int p){
int mid=(l+r)/2;
f(l,mid,ls(p),ca[p]);
f(mid+1,r,rs(p),ca[p]);
ca[p]=-1;
return;
}
void chan(int nl,int nr,int l,int r,int p){
if(nl<=l&&r<=nr){
f(l,r,p,0);
return;
}
pushdown(l,r,p);
int mid=(l+r)/2;
if(mid>=nl){
chan(nl,nr,l,mid,ls(p));
}
if(mid<nr){
chan(nl,nr,mid+1,r,rs(p));
}
pushup(p);
return;
}
int query(int nl,int nr,int l,int r,int p){
if(nl<=l&&r<=nr){
return sum[p];
}
int ret=0;
pushdown(l,r,p);
int mid=(l+r)/2;
if(mid>=nl){
ret+=query(nl,nr,l,mid,ls(p));
}
if(mid<nr){
ret+=query(nl,nr,mid+1,r,rs(p));
}
return ret;
}
void change(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]){
swap(x,y);
}
chan(id[top[y]],id[y],1,n,1);
y=fa[top[y]];
}
if(id[x]>id[y]){
swap(x,y);
}
if(x==y){
return;
}
chan(id[x]+1,id[y],1,n,1);
}
int ask(int x,int y){
int ret=0;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]){
swap(x,y);
}
ret+=query(id[top[y]],id[y],1,n,1);
y=fa[top[y]];
}
if(id[x]>id[y]){
swap(x,y);
}
if(x!=y){
ret+=query(id[x]+1,id[y],1,n,1);
}
return ret;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
unfa[i]=i;
}
for(int i=1;i<=m;i++){
scanf("%lld%lld",&aa[i],&bb[i]);
}
while(1){
Q++;
scanf("%lld",&opt[Q]);
if(opt[Q]==1){
scanf("%lld%lld",&ll[Q],&rr[Q]);
}
else if(opt[Q]==0){
scanf("%lld%lld",&ll[Q],&rr[Q]);
op[make_pair(ll[Q],rr[Q])]=1;
op[make_pair(rr[Q],ll[Q])]=1;
}
else{
break;
}
}
for(int i=1;i<=m;i++){
if(find(aa[i])!=find(bb[i])){
if(op[make_pair(aa[i],bb[i])]!=1){
q[aa[i]].push_back(bb[i]);
q[bb[i]].push_back(aa[i]);
unio(find(aa[i]),find(bb[i]));
}
}
else{
if(op[make_pair(aa[i],bb[i])]!=1){
cnt++;
rest1[cnt]=aa[i];
rest2[cnt]=bb[i];
}
}
}
dfs1(1,0);
dfs2(1,1);
build(1,n,1);
for(int i=1;i<=cnt;i++){
change(rest1[i],rest2[i]);
}
int tem2=0;
for(int i=Q;i>=1;i--){
if(opt[i]==1){
tem2++;
ans[tem2]=ask(ll[i],rr[i]);
}
else if(opt[i]==0){
change(ll[i],rr[i]);
}
}
for(int i=tem2;i>=1;i--){
printf("%lld\n",ans[i]);
}
}