#include<bits/stdc++.h>
using namespace std;
  
using Graph=vector<unordered_set<int>>;
const int REFLESH_INTERVAL=207;
const int PACK=252;
  
int syst=1;
int n;
Graph g;
Graph sG;
vector<int> flag;
vector<int> label;
  
void init(){
    g.resize(n),sG.resize(n);
    flag.resize(n),label.resize(n);
}
  
bool isConnected(int x,int tar){
    if(x==tar) return true;
    if(sG[x].count(tar)) return true;
    for(auto to:sG[x]){
        if(flag[x]!=flag[to]){
            flag[to]=flag[x];
            if(isConnected(to,tar)) return true;
        }            
    }
    return false;
}
void clash(int lab){
    for(auto tol:sG[lab]){
        sG[tol].erase(lab);
    }
    sG[lab].clear();
}
void relabel(int v,int oldLabel){
    for(auto to:g[v]){
        if(label[to]==oldLabel){
            label[to]=label[v];
            relabel(to,oldLabel);
        }            
    }
}
void reSG(int v){
    for(auto to:g[v]){
        if(label[to]==label[v]){
            if(flag[to]!=flag[v]){
                flag[to]=flag[v];
                reSG(to);
            }
        }
        else{
            sG[label[v]].insert(label[to]);
            sG[label[to]].insert(label[v]);
        }
    }
}
bool reSGG(int v,int lab){
    for(auto to:g[v]){
        if(label[to]==lab) return true;
        if(flag[v]!=flag[to] && label[v]==label[to]){
            flag[to]=flag[v];
            if(reSGG(to,lab)) return true;
        } 
    }
    return false;
}
void fleshLabel(int v,int &cnt){
    for(auto to:g[v]){
        if(cnt==0) break;
        if(label[to]==-1){
            label[to]=label[v];
            cnt--;
            if(cnt){
                fleshLabel(to,cnt);
            }
        }
        // else{
        //     if(label[to]!=label[v]){
        //         sG[label[v]].insert(label[to]);
        //         sG[label[to]].insert(label[v]);
        //     }
        // }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int k;
    cin>>n>>k;
    init();
    iota(label.begin(),label.end(),0);
      
    int refleshCnt=REFLESH_INTERVAL;
    stack<int> labst;
    while(k--){
        syst++;
        int type,u,v;
        cin>>type>>u>>v;
        if(type==1){
            g[u].insert(v);
            g[v].insert(u);
            if(label[u]!=label[v]){
                sG[label[u]].insert(label[v]);
                sG[label[v]].insert(label[u]);
            }
        }
        else if(type==2){
            g[u].erase(v);
            g[v].erase(u);
            if(label[u]==label[v]){
                int ulabel=label[u];
                int newlabel=labst.top(); labst.pop();
                label[v]=newlabel;
                relabel(v,ulabel);
                if(label[u]==label[v]){
                    labst.push(ulabel);
                    clash(ulabel);
                }
                clash(label[u]);
                flag[u]=syst++;
                reSG(u);
                clash(label[v]);
                flag[v]=syst++;
                reSG(v);
            }
            else{
                sG[label[u]].erase(label[v]);
                sG[label[v]].erase(label[u]);
                flag[u]=syst++;
                if(reSGG(u,label[v])){
                    sG[label[u]].insert(label[v]);
                    sG[label[v]].insert(label[u]);
                }
            }
        }
        else{
            flag[label[u]]=syst++;
            cout<<(isConnected(label[u],label[v]) ? "YES\n" : "NO\n");
        }
  
        if(!refleshCnt){
            fill(label.begin(),label.end(),-1);
            for(int i=0;i<n;i++) sG[i].clear();
            labst=stack<int>();
            int nexLabel=0;
            for(int i=0;i<n;i++){
                if(label[i]==-1){
                    label[i]=nexLabel++;
                    int cnt=PACK-1;
                    fleshLabel(i,cnt);
                }
            }
            for(int i=0;i<n;i++){
                if(flag[i]!=syst){
                    reSG(i);                    
                }
            }
            syst++;
            for(int i=nexLabel;i<n;i++) labst.push(i);
            refleshCnt=REFLESH_INTERVAL;
        }
        else{
            refleshCnt--;
        }
    }
  
    return 0;
}


Measured memory_bytes: 12412