#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ll long long
const int N=1050;
vector<pair<int,int>>E[N];
vector<pair<int,int> >E1[N][N];
int par[N];
int FS(int u){
    if(par[u]==u) return u;
    return par[u]=FS(par[u]);
}
void US(int u,int v) {int x=FS(u),y=FS(v);par[x]=y;}
/*bool res,was[N][N];
pair<int,int>nesto[N*N];
int CT=0;
void DFS(int u,int v,int parent1,int parent2){
    //printf("%i %i %i %i\n",u,v,parent1,parent2);
    if(u>v) swap(u,v),swap(parent1,parent2);
    was[u][v]=true;
    CT++;nesto[CT]={u,v};
    if(u==v || parent1==v || parent2==u) {res=true;return;}
    for(auto i:E[u]){
        for(auto j:E[v]){
            if(i.se==j.se && was[i.fi][j.fi]==false && !(i.fi<u && v<j.fi)) DFS(i.fi,j.fi,u,v);
            if(res) return;
        }
    }
}*/
bool res,was[N][N];
pair<int,int>nesto[N*N];
int CT=0;
void DFS(int u,int v,int parent1,int parent2){
    //printf("%i %i %i %i\n",u,v,parent1,parent2);
    //if(u>v) swap(u,v),swap(parent1,parent2);
    was[u][v]=true;
    CT++;nesto[CT]={u,v};
    if(u==v || parent1==v || parent2==u) {res=true;return;}
    for(auto i:E1[u][v]) if(!was[i.fi][i.se]) DFS(i.fi,i.se,u,v);
}
int dp[N][N],edges[N][N];
int main()
{
    bool subtask1=true,subtask2=true;
    int n,q;scanf("%i%i",&n,&q);
    for(int i=1;i<=n;i++) par[i]=i;
    for(int i=1;i<=n;i++) dp[i][i]=1;

    int type1[q+10],u1[q+10],v1[q+10];char c1[q+10];
    for(int I=1;I<=q;I++){
        scanf("%i%i%i",&type1[I],&u1[I],&v1[I]);
        if(type1[I]==1) {cin>>c1[I];if(c1[I]!='a') subtask1=false;}
        if(type1[I]==1 && v1[I]!=u1[I]+1) subtask2=false;
    }

    for(int I=1;I<=q;I++){
        int type;type=type1[I];//scanf("%i",&type);
        if(type==1){
            int u,v;char c;u=u1[I],v=v1[I],c=c1[I];//scanf("%i%i",&u,&v);cin>>c;
            int C=c-'a'+1;
            E[u].pb({v,C}),E[v].pb({u,C});
            US(u,v);
            if(subtask1) continue;
            edges[u][v]=edges[v][u]=C;
            for(int i=1;i<=n;i++){
                for(auto j:E[i]){
                    if(j.se==C){
                        E1[u][i].pb({v,j.fi});
                        E1[i][u].pb({v,j.fi});
                        E1[u][i].pb({j.fi,v});
                        E1[i][u].pb({j.fi,v});

                        E1[v][i].pb({u,j.fi});
                        E1[i][v].pb({u,j.fi});
                        E1[v][i].pb({j.fi,u});
                        E1[i][v].pb({j.fi,u});
                    }
                }
            }
            /*dp[u][v]=dp[v][u]=1;
            queue<pair<int,int> >a;
            bool wasu[N]={false},wasv[N]={false};
            a.push({u,v}),a.push({v,u});
            while(a.size()){
                int x=a.front().fi,y=a.front().se;
                a.pop();
                if(y==u) wasu[x]=true;
                else wasv[x]=true;
                int y1=u;if(y==u) y1=v;
                for(auto i:E[x]){
                    if(i.se==C) dp[x][y]=max(dp[x][y],dp[i.fi][y1]);
                    if((y==u && !wasu[i.fi]) || (y==v && !wasv[i.fi])) a.push({i.fi,y});
                }
                dp[y][x]=dp[x][y];
            }*/
            /*for(int i=1;i<=n;i++){
                for(auto j:E[i]){
                    if(j.se==C) {dp[u][i]=dp[i][u]=dp[v][j.fi];dp[v][i]=dp[i][v]=dp[u][j.fi];}
                }
            }*/
            /*vector<int>a,b;
            for(int i=1;i<=n;i++){
                if(dp[v][i]==0) continue;
                for(auto j:E[i]) if(j.se==C) a.pb(j.fi);
            }
            for(int i=1;i<=n;i++){
                if(dp[u][i]==0) continue;
                for(auto j:E[i]) if(j.se==C) b.pb(j.fi);
            }
            while(a.size()) {dp[u][a.back()]=dp[a.back()][u]=1;a.pop_back();}
            while(b.size()) {dp[v][b.back()]=dp[b.back()][v]=1;b.pop_back();}*/
        }
        else{
            int u,v;u=u1[I],v=v1[I];//scanf("%i%i",&u,&v);
            if(FS(u)!=FS(v)) {printf("0\n");continue;}
            if(subtask1) {printf("%i\n",FS(u)==FS(v));continue;}
            if(u>v) swap(u,v);
            /*bool res=false;
            bool Was[N][N];
            memset(Was,0,sizeof(Was));
            queue<pair<int,int> >q;
            q.push({u,v});
            while(q.size()){
                int U=q.front().fi,V=q.front().se;q.pop();
                Was[U][V]=true;
                if(abs(U-V)<=1) {res=true;break;}
                if(edges[U][U+1] && edges[V-1][V] && edges[U][U+1]==edges[V-1][V]) q.push({U+1,V-1});
                if(edges[U][U+1] && edges[V][V+1] && edges[U][U+1]==edges[V][V+1] && !Was[U+1][V+1]) q.push({U+1,V+1});
                if(edges[U-1][U] && edges[V-1][V] && edges[U-1][U]==edges[V-1][V] && !Was[U-1][V-1]) q.push({U-1,V-1});
            }
            /*while(q.size()){
                int U=q.front().fi,V=q.front().se;q.pop();
                if(abs(U-V)<=1) {res=true;break;}
                if(edges[U][U+1] && edges[V-1][V] && edges[U][U+1]==edges[V-1][V]) q.push({U+1,V-1});
                if(edges[U][U+1] && edges[V][V+1] && edges[U][U+1]==edges[V][V+1]) q.push({U+1,V+1});
            }
            while(q.size()) q.pop();
            q.push({u,v});
            while(q.size()){
                int U=q.front().fi,V=q.front().se;q.pop();
                if(abs(U-V)<=1) {res=true;break;}
                if(edges[U][U+1] && edges[V-1][V] && edges[U][U+1]==edges[V-1][V]) q.push({U+1,V-1});
                if(edges[U-1][U] && edges[V-1][V] && edges[U-1][U]==edges[V-1][V]) q.push({U-1,V-1});
            }*/
            //printf("%i\n",res);
            //for(int i=1;i<=n;i++) {for(int j=1;j<=n;j++) printf("%i ",dp[i][j]);printf("\n");}
            //printf("%i\n",dp[u][v]);
            //for(int i=0;i<N;i++) for(int j=0;j<N;j++) was[i][j]=false;
            //if(subtask2){
                DFS(u,v,0,0);
                printf("%i\n",res);
                res=false;
                while(CT>0){
                    int x=nesto[CT].fi,y=nesto[CT].se;CT--;
                    was[x][y]=was[y][x]=false;
                }
            //}
        }
        //printf("%i--\n",I);
    }
    return 0;
}