#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
using namespace std;
typedef pair<int,int> pii;
typedef vector<pii> vp;
typedef vector<int> vi;
typedef struct DSU{
vector<int> par,ra;
int s;
DSU(int _n) : par(_n+1), ra(_n+1), s(0){
for(int i=0;i<=_n;i++) par[i]=i;
}
int fi(int x){
while(par[x]!=x) x=par[x];
return x;
}
pii un(int a, int b){
a=fi(a); b=fi(b);
if(a==b) return mp(-1,-1);
if(ra[a]>ra[b]) swap(a,b);
par[a]=b;
if(ra[a]==ra[b]) ra[b]++;
s++;
return mp(a,b); //a를 b에 합쳤음
}
void undo(int a, int b){
par[a]=a;
if(ra[b]==ra[a]+1) ra[b]--;
s--;
}
}DSU;
int n,q;
vector<vp> tree;
DSU uf(300005);
void update(int node, int st, int en, int le, int ri, pii e){
if(ri<st || en<le) return;
if(le<=st && en<=ri){
tree[node].pb(e);
return;
}
int mid=(st+en)>>1;
update(node*2,st,mid,le,ri,e);
update(node*2+1,mid+1,en,le,ri,e);
}
void dfs(int node, int st, int en){
vector<pii> tv;
for(pii k : tree[node]){
tv.push_back(uf.un(k.first,k.second));
}
if(st!=en){
int mid=(st+en)>>1;
dfs(node*2,st,mid);
dfs(node*2+1,mid+1,en);
}
else{
printf("%d\n",n-uf.s);
}
while(!tv.empty()){
pii k=tv.back(); tv.pop_back();
if(k.first==-1) continue;
uf.undo(k.first,k.second);
}
}
map<pii, int> M;
vector<pair<pii,pii> > query;
int main(){
freopen("connect.in","r",stdin);
freopen("connect.out","w",stdout);
scanf("%d %d",&n,&q);
int time=1;
for(int i=1;i<=q;i++){
char sel;
int t1,t2;
scanf(" %c",&sel);
if(sel=='?') time++;
else if(sel=='+' || sel=='-'){
scanf("%d %d",&t1,&t2);
if(t1>t2) swap(t1,t2);
if(M[mp(t1,t2)]){
query.emplace_back(mp(t1,t2),mp(M[mp(t1,t2)],time));
M[mp(t1,t2)]=0;
}
else M[mp(t1,t2)]=time;
}
}
for(auto it : M){
if(it.second)
query.emplace_back(it.first,mp(it.second,time));
}
tree.assign(5*(time+2),vp());
for(auto k : query){
pii idx=k.first;
pii life=k.second; life.second--;
if(life.second<life.first) continue;
//printf("$%d %d %d %d\n",idx.first,idx.second,life.first,life.second);
update(1,1,time-1,life.first,life.second,idx);
}
dfs(1,1,time-1);
return 0;
}
//ryute:cyanine
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgbXAgbWFrZV9wYWlyCiNkZWZpbmUgcGIgcHVzaF9iYWNrCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp0eXBlZGVmIHBhaXI8aW50LGludD4gcGlpOwp0eXBlZGVmIHZlY3RvcjxwaWk+IHZwOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwoKdHlwZWRlZiBzdHJ1Y3QgRFNVewogICAgdmVjdG9yPGludD4gcGFyLHJhOwogICAgaW50IHM7CiAgICBEU1UoaW50IF9uKSA6IHBhcihfbisxKSwgcmEoX24rMSksIHMoMCl7CiAgICAgICAgZm9yKGludCBpPTA7aTw9X247aSsrKSBwYXJbaV09aTsKICAgIH0KICAgIGludCBmaShpbnQgeCl7CiAgICAgICAgd2hpbGUocGFyW3hdIT14KSB4PXBhclt4XTsKICAgICAgICByZXR1cm4geDsKICAgIH0KICAgIHBpaSB1bihpbnQgYSwgaW50IGIpewogICAgICAgIGE9ZmkoYSk7IGI9ZmkoYik7CiAgICAgICAgaWYoYT09YikgcmV0dXJuIG1wKC0xLC0xKTsKICAgICAgICBpZihyYVthXT5yYVtiXSkgc3dhcChhLGIpOwogICAgICAgIHBhclthXT1iOwogICAgICAgIGlmKHJhW2FdPT1yYVtiXSkgcmFbYl0rKzsKICAgICAgICBzKys7CiAgICAgICAgcmV0dXJuIG1wKGEsYik7IC8vYeulvCBi7JeQIO2VqeyzpOydjAogICAgfQogICAgdm9pZCB1bmRvKGludCBhLCBpbnQgYil7CiAgICAgICAgcGFyW2FdPWE7CiAgICAgICAgaWYocmFbYl09PXJhW2FdKzEpIHJhW2JdLS07CiAgICAgICAgcy0tOwogICAgfQp9RFNVOwoKaW50IG4scTsKdmVjdG9yPHZwPiB0cmVlOwpEU1UgdWYoMzAwMDA1KTsKCnZvaWQgdXBkYXRlKGludCBub2RlLCBpbnQgc3QsIGludCBlbiwgaW50IGxlLCBpbnQgcmksIHBpaSBlKXsKICAgIGlmKHJpPHN0IHx8IGVuPGxlKSByZXR1cm47CiAgICBpZihsZTw9c3QgJiYgZW48PXJpKXsKICAgICAgICB0cmVlW25vZGVdLnBiKGUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGludCBtaWQ9KHN0K2VuKT4+MTsKICAgIHVwZGF0ZShub2RlKjIsc3QsbWlkLGxlLHJpLGUpOwogICAgdXBkYXRlKG5vZGUqMisxLG1pZCsxLGVuLGxlLHJpLGUpOwp9Cgp2b2lkIGRmcyhpbnQgbm9kZSwgaW50IHN0LCBpbnQgZW4pewogICAgdmVjdG9yPHBpaT4gdHY7CiAgICBmb3IocGlpIGsgOiB0cmVlW25vZGVdKXsKICAgICAgICB0di5wdXNoX2JhY2sodWYudW4oay5maXJzdCxrLnNlY29uZCkpOwogICAgfQogICAgaWYoc3QhPWVuKXsKICAgICAgICBpbnQgbWlkPShzdCtlbik+PjE7CiAgICAgICAgZGZzKG5vZGUqMixzdCxtaWQpOwogICAgICAgIGRmcyhub2RlKjIrMSxtaWQrMSxlbik7CiAgICB9CiAgICBlbHNlewogICAgICAgIHByaW50ZigiJWRcbiIsbi11Zi5zKTsKICAgIH0KICAgIHdoaWxlKCF0di5lbXB0eSgpKXsKICAgICAgICBwaWkgaz10di5iYWNrKCk7IHR2LnBvcF9iYWNrKCk7CiAgICAgICAgaWYoay5maXJzdD09LTEpIGNvbnRpbnVlOwogICAgICAgIHVmLnVuZG8oay5maXJzdCxrLnNlY29uZCk7CiAgICB9Cn0KCm1hcDxwaWksIGludD4gTTsKdmVjdG9yPHBhaXI8cGlpLHBpaT4gPiBxdWVyeTsKCmludCBtYWluKCl7CiAgICBmcmVvcGVuKCJjb25uZWN0LmluIiwiciIsc3RkaW4pOwogICAgZnJlb3BlbigiY29ubmVjdC5vdXQiLCJ3IixzdGRvdXQpOwogICAgc2NhbmYoIiVkICVkIiwmbiwmcSk7CgogICAgaW50IHRpbWU9MTsKICAgIGZvcihpbnQgaT0xO2k8PXE7aSsrKXsKICAgICAgICBjaGFyIHNlbDsKICAgICAgICBpbnQgdDEsdDI7CiAgICAgICAgc2NhbmYoIiAlYyIsJnNlbCk7CiAgICAgICAgaWYoc2VsPT0nPycpIHRpbWUrKzsKICAgICAgICBlbHNlIGlmKHNlbD09JysnIHx8IHNlbD09Jy0nKXsKICAgICAgICAgICAgc2NhbmYoIiVkICVkIiwmdDEsJnQyKTsKICAgICAgICAgICAgaWYodDE+dDIpIHN3YXAodDEsdDIpOwogICAgICAgICAgICBpZihNW21wKHQxLHQyKV0pewogICAgICAgICAgICAgICAgcXVlcnkuZW1wbGFjZV9iYWNrKG1wKHQxLHQyKSxtcChNW21wKHQxLHQyKV0sdGltZSkpOwogICAgICAgICAgICAgICAgTVttcCh0MSx0MildPTA7CiAgICAgICAgICAgIH0gCiAgICAgICAgICAgIGVsc2UgTVttcCh0MSx0MildPXRpbWU7CiAgICAgICAgfQogICAgfQogICAgZm9yKGF1dG8gaXQgOiBNKXsKICAgICAgICBpZihpdC5zZWNvbmQpCiAgICAgICAgICAgIHF1ZXJ5LmVtcGxhY2VfYmFjayhpdC5maXJzdCxtcChpdC5zZWNvbmQsdGltZSkpOwogICAgfQogICAgdHJlZS5hc3NpZ24oNSoodGltZSsyKSx2cCgpKTsKICAgIGZvcihhdXRvIGsgOiBxdWVyeSl7CiAgICAgICAgcGlpIGlkeD1rLmZpcnN0OwogICAgICAgIHBpaSBsaWZlPWsuc2Vjb25kOyBsaWZlLnNlY29uZC0tOwogICAgICAgIGlmKGxpZmUuc2Vjb25kPGxpZmUuZmlyc3QpIGNvbnRpbnVlOwogICAgICAgIC8vcHJpbnRmKCIkJWQgJWQgJWQgJWRcbiIsaWR4LmZpcnN0LGlkeC5zZWNvbmQsbGlmZS5maXJzdCxsaWZlLnNlY29uZCk7CiAgICAgICAgdXBkYXRlKDEsMSx0aW1lLTEsbGlmZS5maXJzdCxsaWZlLnNlY29uZCxpZHgpOwogICAgfQogICAgZGZzKDEsMSx0aW1lLTEpOwogICAgcmV0dXJuIDA7Cn0KCi8vcnl1dGU6Y3lhbmluZQ==