#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=6e5+5;
int n,m,q,ans[N];vector<int>adj[N];vector<array<int,2>>ed;vector<vector<int>>seg,add(N),cut(N);
struct dsu
{
int parent[N],group[N],res;stack<array<int,4>>st;
dsu()
{
for(int i=0;i<N;i++)
{
parent[i]=i;
group[i]=1;
}
}
void set(int x){
res=x;
}
int find(int i)
{
if(parent[i]==i)
{
return i;
}
return find(parent[i]);
}
bool samegroup(int x,int y)
{
return find(x)==find(y);
}
void merge(int x,int y)
{
int leader1=find(x);
int leader2=find(y);
if(group[leader1]>group[leader2])
{
swap(leader1,leader2);
}
array<int,4>p={0,0,0,0};
p[0]=leader2,p[1]=group[leader2];
p[2]=leader1,p[3]=parent[leader1];
st.push(p);
if(leader1==leader2)
{
return;
}
res--;
group[leader2]+=group[leader1];
parent[leader1]=leader2;
}
int getsize(int x)
{
return group[find(x)];
}
int getans()
{
return res;
}
void rollBack()
{
if(st.empty())return;
auto &[a,b,c,d]=st.top();
st.pop();
group[a]=b;
parent[c]=d;
res+=!samegroup(a,c);
}
}d;
void update(int l,int r,int node,int lx,int rx,int idx)
{
if(r<lx||l>rx) return;
if(l>=lx&&r<=rx)
{
seg[node].push_back(idx);
return;
}
int mid=l+r>>1;
update(l,mid,2*node+1,lx,rx,idx);
update(mid+1,r,2*node+2,lx,rx,idx);
}
void build(int l,int r,int node)
{
for(auto it:seg[node])
{
d.merge(ed[it][0],ed[it][1]);
}
if(l==r)
{
ans[l]=d.getans();
for(auto it:seg[node]) d.rollBack();
return;
}
int mid=l+r>>1;
build(l,mid,2*node+1);
build(mid+1,r,2*node+2);
for(auto it:seg[node]) d.rollBack();
}
signed main()
{
freopen("connect.in","r",stdin);
freopen("connect.out","w",stdout);
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>q;
map<array<int,2>,int>mp;
ed.push_back({0,0});
vector<int>queries;
for(int i=1;i<=q;i++)
{
char op;cin>>op;
if(op=='?') queries.push_back(i);
else
{
int a,b;cin>>a>>b;
if(b>a)swap(a,b);
if(op=='+')
{
if(mp.find({a,b})==mp.end()) ed.push_back({a,b}),mp[ed.back()]=ed.size()-1;
int idx=mp[{a,b}];
add[idx].push_back(i);
}
else
{
int idx=mp[{a,b}];
cut[idx].push_back(i);
}
}
}
for(int i=1;i<ed.size();i++) cut[i].push_back(q+1);
int sz=1;
while(sz<=q+5)sz<<=1;
seg=vector<vector<int>>(sz<<1);
for(int i=1;i<ed.size();i++)
{
for(auto it:add[i])
{
update(0,sz-1,0,it,*lower_bound(cut[i].begin(),cut[i].end(),it)-1,i);
}
}
d.set(n);
build(0,sz-1,0);
for(auto it:queries) cout<<ans[it]<<'\n';
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgbGwgbG9uZyBsb25nCmNvbnN0IGludCBOPTZlNSs1OwppbnQgbixtLHEsYW5zW05dO3ZlY3RvcjxpbnQ+YWRqW05dO3ZlY3RvcjxhcnJheTxpbnQsMj4+ZWQ7dmVjdG9yPHZlY3RvcjxpbnQ+PnNlZyxhZGQoTiksY3V0KE4pOwpzdHJ1Y3QgZHN1CnsKICAgIGludCBwYXJlbnRbTl0sZ3JvdXBbTl0scmVzO3N0YWNrPGFycmF5PGludCw0Pj5zdDsKICAgIGRzdSgpCiAgICB7CiAgICAgICAgZm9yKGludCBpPTA7aTxOO2krKykKICAgICAgICB7CiAgICAgICAgICAgIHBhcmVudFtpXT1pOwogICAgICAgICAgICBncm91cFtpXT0xOwogICAgICAgIH0KICAgIH0KICAgIHZvaWQgc2V0KGludCB4KXsKICAgICAgICByZXM9eDsKICAgIH0KICAgIGludCBmaW5kKGludCBpKQogICAgewogICAgICAgIGlmKHBhcmVudFtpXT09aSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmluZChwYXJlbnRbaV0pOwogICAgfQogICAgYm9vbCBzYW1lZ3JvdXAoaW50IHgsaW50IHkpCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbmQoeCk9PWZpbmQoeSk7CiAgICB9CiAgICB2b2lkIG1lcmdlKGludCB4LGludCB5KQogICAgewogICAgICAgIGludCBsZWFkZXIxPWZpbmQoeCk7CiAgICAgICAgaW50IGxlYWRlcjI9ZmluZCh5KTsKICAgICAgICBpZihncm91cFtsZWFkZXIxXT5ncm91cFtsZWFkZXIyXSkKICAgICAgICB7CiAgICAgICAgICAgIHN3YXAobGVhZGVyMSxsZWFkZXIyKTsKICAgICAgICB9CiAgICAgICAgYXJyYXk8aW50LDQ+cD17MCwwLDAsMH07CiAgICAgICAgcFswXT1sZWFkZXIyLHBbMV09Z3JvdXBbbGVhZGVyMl07CiAgICAgICAgcFsyXT1sZWFkZXIxLHBbM109cGFyZW50W2xlYWRlcjFdOwogICAgICAgIHN0LnB1c2gocCk7CiAgICAgICAgaWYobGVhZGVyMT09bGVhZGVyMikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgcmVzLS07CiAgICAgICAgZ3JvdXBbbGVhZGVyMl0rPWdyb3VwW2xlYWRlcjFdOwogICAgICAgIHBhcmVudFtsZWFkZXIxXT1sZWFkZXIyOwogICAgfQogICAgaW50IGdldHNpemUoaW50IHgpCiAgICB7CiAgICAgICAgcmV0dXJuIGdyb3VwW2ZpbmQoeCldOwogICAgfQogICAgaW50IGdldGFucygpCiAgICB7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KICAgIHZvaWQgcm9sbEJhY2soKQogICAgewogICAgICAgIGlmKHN0LmVtcHR5KCkpcmV0dXJuOwogICAgICAgIGF1dG8gJlthLGIsYyxkXT1zdC50b3AoKTsKICAgICAgICBzdC5wb3AoKTsKICAgICAgICBncm91cFthXT1iOwogICAgICAgIHBhcmVudFtjXT1kOwogICAgICAgIHJlcys9IXNhbWVncm91cChhLGMpOwogICAgfQp9ZDsKdm9pZCB1cGRhdGUoaW50IGwsaW50IHIsaW50IG5vZGUsaW50IGx4LGludCByeCxpbnQgaWR4KQp7CiAgICBpZihyPGx4fHxsPnJ4KSByZXR1cm47CiAgICBpZihsPj1seCYmcjw9cngpCiAgICB7CiAgICAgICAgc2VnW25vZGVdLnB1c2hfYmFjayhpZHgpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGludCBtaWQ9bCtyPj4xOwogICAgdXBkYXRlKGwsbWlkLDIqbm9kZSsxLGx4LHJ4LGlkeCk7CiAgICB1cGRhdGUobWlkKzEsciwyKm5vZGUrMixseCxyeCxpZHgpOwp9CnZvaWQgYnVpbGQoaW50IGwsaW50IHIsaW50IG5vZGUpCnsKICAgIGZvcihhdXRvIGl0OnNlZ1tub2RlXSkKICAgIHsKICAgICAgICBkLm1lcmdlKGVkW2l0XVswXSxlZFtpdF1bMV0pOwogICAgfQogICAgaWYobD09cikKICAgIHsKICAgICAgICBhbnNbbF09ZC5nZXRhbnMoKTsKICAgICAgICBmb3IoYXV0byBpdDpzZWdbbm9kZV0pIGQucm9sbEJhY2soKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpbnQgbWlkPWwrcj4+MTsKICAgIGJ1aWxkKGwsbWlkLDIqbm9kZSsxKTsKICAgIGJ1aWxkKG1pZCsxLHIsMipub2RlKzIpOwogICAgZm9yKGF1dG8gaXQ6c2VnW25vZGVdKSBkLnJvbGxCYWNrKCk7Cn0Kc2lnbmVkIG1haW4oKQp7CiAgICBmcmVvcGVuKCJjb25uZWN0LmluIiwiciIsc3RkaW4pOwogICAgZnJlb3BlbigiY29ubmVjdC5vdXQiLCJ3IixzdGRvdXQpOwogICAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbygwKTtjaW4udGllKDApO2NvdXQudGllKDApOwogICAgY2luPj5uPj5xOwogICAgbWFwPGFycmF5PGludCwyPixpbnQ+bXA7CiAgICBlZC5wdXNoX2JhY2soezAsMH0pOwogICAgdmVjdG9yPGludD5xdWVyaWVzOwogICAgZm9yKGludCBpPTE7aTw9cTtpKyspCiAgICB7CiAgICAgICAgY2hhciBvcDtjaW4+Pm9wOwogICAgICAgIGlmKG9wPT0nPycpIHF1ZXJpZXMucHVzaF9iYWNrKGkpOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGludCBhLGI7Y2luPj5hPj5iOwogICAgICAgICAgICBpZihiPmEpc3dhcChhLGIpOwogICAgICAgICAgICBpZihvcD09JysnKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZihtcC5maW5kKHthLGJ9KT09bXAuZW5kKCkpIGVkLnB1c2hfYmFjayh7YSxifSksbXBbZWQuYmFjaygpXT1lZC5zaXplKCktMTsKICAgICAgICAgICAgICAgIGludCBpZHg9bXBbe2EsYn1dOwogICAgICAgICAgICAgICAgYWRkW2lkeF0ucHVzaF9iYWNrKGkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGlkeD1tcFt7YSxifV07CiAgICAgICAgICAgICAgICBjdXRbaWR4XS5wdXNoX2JhY2soaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmb3IoaW50IGk9MTtpPGVkLnNpemUoKTtpKyspIGN1dFtpXS5wdXNoX2JhY2socSsxKTsKICAgIGludCBzej0xOwogICAgd2hpbGUoc3o8PXErNSlzejw8PTE7CiAgICBzZWc9dmVjdG9yPHZlY3RvcjxpbnQ+Pihzejw8MSk7CiAgICBmb3IoaW50IGk9MTtpPGVkLnNpemUoKTtpKyspCiAgICB7CiAgICAgICAgZm9yKGF1dG8gaXQ6YWRkW2ldKQogICAgICAgIHsKICAgICAgICAgICAgdXBkYXRlKDAsc3otMSwwLGl0LCpsb3dlcl9ib3VuZChjdXRbaV0uYmVnaW4oKSxjdXRbaV0uZW5kKCksaXQpLTEsaSk7CiAgICAgICAgfQogICAgfQogICAgZC5zZXQobik7CiAgICBidWlsZCgwLHN6LTEsMCk7CiAgICBmb3IoYXV0byBpdDpxdWVyaWVzKSBjb3V0PDxhbnNbaXRdPDwnXG4nOwogICAgcmV0dXJuIDA7Cn0=