#include <bits/stdc++.h>
#define endl '\n'
#define ll int
#define pb push_back
#define pll pair<ll,ll>
#define si(a) ((ll)(a.size()))
#define fi first
#define sc second
#define here cerr<<"==============================\n"
#define llinf 100000000000000LL
using namespace std;
#define maxn 1005
#define maxq 300005
ll n,q;
vector<pll> g[27][maxn];
map<pll,ll> dp[27];
array<ll,4> Q[maxq];
set<array<ll,3> > pq[maxq];
ll dsu[maxn];
ll root(ll x){while(dsu[x]!=x){dsu[x] = dsu[dsu[x]]; x = dsu[x];} return x;}
void upd(ll x,ll y){x = root(x);y = root(y);dsu[x] = y;}
bool ok1 = 1;
bool ok2 = 1;
int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cerr.tie(0);
    cin >> n >> q;
    for(ll i = 1;i<=q;i++){
        ll tip; cin >> tip;
        ll x,y; char c;
        if(tip==1){
            cin >> x >> y >> c;
            if(abs(x-y)>1) ok2 = 0;
            if(c!='a') ok1 = 0;
            ll val = c-'a'+1;
            Q[i] = {tip,x,y,c-'a'+1};
            g[val][x].pb({y,i});
            g[val][y].pb({x,i});
            pq[i].insert({0,x,y});
            dp[0][{x,y}] = dp[0][{y,x}] = i;
        }else{
            cin >> x >> y;
            Q[i] = {tip,x,y,0};
        }
    }
    if(ok1){
        iota(dsu+1,dsu+1+n,1);
        for(ll i = 1;i<=q;i++){
            ll tip = Q[i][0],x = Q[i][1],y = Q[i][2];
            if(tip==1) upd(x,y);
            else cout<<(root(x)==root(y))<<endl;
        }
        return 0;
    }
    if(!ok2&&n>100) return 0;
    for(ll i = 1;i<=n;i++) pq[0].insert({0,i,i});
    for(ll ti = 0;ti<=q;ti++){
        for(auto p : pq[ti]) {
            ll x = p[1],y = p[2],e = p[0];
            //cerr<<x<< " "<<y<<" "<<e<<" "<<endl;
            if(ti!=dp[e][{x,y}]) continue;
            if(e!=0){
                for(pll py : g[e][y]){
                    ll sy = py.fi;
                    ll dy = py.sc;
                    ll d = max(dy,ti);
                    ll &val = dp[0][{x,sy}];
                    if(d<val||val==0){
                        if(val!=0) if(pq[val].find({0,x,sy})!=pq[val].end()) pq[val].erase(pq[val].find({0,x,sy}));
                        if(val!=0) if(pq[val].find({0,x,sy})!=pq[val].end()) pq[val].erase(pq[val].find({0,sy,x}));
                        val = dp[0][{sy,x}] = d;
                        pq[d].insert({0,x,sy});
                    }
                }
            }else{
                for(ll f = 0;f<2;f++){
                    for(ll e = 1;e<=26;e++){
                        for(pll py : g[e][y]){
                            ll sy = py.fi;
                            ll dy = py.sc;
                            ll d = max(dy,ti);
                            ll &val = dp[e][{sy,x}];
                            if(d<val||val==0){
                                if(val!=0) pq[val].erase(pq[val].find({e,sy,x}));
                                val = d;
                                pq[d].insert({e,sy,x});
                            }
                        }
                    }
                    swap(x,y);
                }
            }
        }
        set<array<ll,3> > tmp;
        pq[ti].swap(tmp);
    }
    for(ll i = 1;i<=q;i++){
        if(Q[i][0]==1) continue;
        ll x = Q[i][1],y = Q[i][2];
        if(x==y) cout<<1<<endl;
        else if(dp[0][{x,y}]>0&&dp[0][{x,y}]<=i) cout<<1<<endl;
        else cout<<0<<endl;
    }
    return 0;
}