#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define int long long
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
#define put putchar('\n')
using namespace std;
inline int read(){
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f*x;
}
inline void print(int x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
const int N=1e5+5;
int seg[N],top[N],n,m,op[N],siz[N],father[N],son[N],ans[N];
int rev[N],cnt,q,u[N],v[N],b[N],dep[N],s[N],t[N],tot;
vector<int> a[N];
map<pair<int,int>,int> ok;
inline void dfs1(int x,int fa){
b[x]=1,siz[x]=1,father[x]=fa,dep[x]=dep[fa]+1;
for(int i=0;i<a[x].size();i++){
if(b[a[x][i]]||a[x][i]==fa||ok[make_pair(a[x][i],x)]) continue;
ok[make_pair(a[x][i],x)]=2;ok[make_pair(x,a[x][i])]=2;
dfs1(a[x][i],x);
siz[x]+=siz[a[x][i]];
if(siz[son[x]]<siz[a[x][i]]) son[x]=a[x][i];
}
}
inline void dfs2(int x,int topf){
b[x]=0,seg[x]=++cnt,top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i=0;i<a[x].size();i++){
if(!b[a[x][i]]||ok[make_pair(x,a[x][i])]==1||father[x]==a[x][i]) continue;
dfs2(a[x][i],a[x][i]);
}
}
struct node{
int l,r,sum,tag;
}tree[N<<2];
inline void build(int x,int l,int r){
tree[x].l=l,tree[x].r=r,tree[x].sum=r-l+1,tree[x].tag=-1;
if(l==1) tree[x].sum--;
if(l==r) return;
build(ls(x),l,mid);build(rs(x),mid+1,r);
}
inline void pushdown(int x){
if(tree[x].tag!=-1){
tree[ls(x)].tag=tree[rs(x)].tag=0;
tree[ls(x)].sum=tree[rs(x)].sum=0;
tree[x].tag=-1;
}
}
inline void change(int x,int l,int r){
if(tree[x].l>=l&&tree[x].r<=r){
tree[x].tag=0;
tree[x].sum=0;
return;
}
if(tree[x].l>r||tree[x].r<l) return;
pushdown(x);
change(ls(x),l,r);change(rs(x),l,r);
tree[x].sum=tree[ls(x)].sum+tree[rs(x)].sum;
}
inline void Change(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(1,seg[top[x]],seg[x]);
x=father[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(1,seg[x]+1,seg[y]);
}
inline int query(int x,int l,int r){
if(tree[x].l>=l&&tree[x].r<=r) return tree[x].sum;
if(tree[x].l>r||tree[x].r<l) return 0;
pushdown(x);
return query(ls(x),l,r)+query(rs(x),l,r);
}
inline int Query(int x,int y){
int sum=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
sum+=query(1,seg[top[x]],seg[x]);
x=father[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return sum+query(1,seg[x]+1,seg[y]);
}
signed main(){
n=read(),m=read();
for(int i=1,u,v;i<=m;i++){
s[i]=read(),t[i]=read();
a[s[i]].push_back(t[i]);
a[t[i]].push_back(s[i]);
}
while(1){
++q;op[q]=read();
if(op[q]==-1) break;
u[q]=read(),v[q]=read();
if(op[q]==0) {
ok[make_pair(u[q],v[q])]=1;
ok[make_pair(v[q],u[q])]=1;
}
}
dfs1(1,0);dfs2(1,1);build(1,1,n);
for(int i=1;i<=m;i++){
if(!ok[make_pair(s[i],t[i])]) Change(s[i],t[i]);
}
for(int i=q-1;i>=1;i--){
if(op[i]==1){
ans[++tot]=Query(u[i],v[i]);
}
else {
Change(u[i],v[i]);
}
}
for(int i=tot;i>=1;--i) print(ans[i]),put;
return 0;
}