#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, SQ = 5555;
unordered_map<int, int> ed[N];
set<pair<int, int>> edge, bad;
int n, m, k, last, par[N];
struct Query {
  int t, u, v;
} qu[SQ];
bool mark[N];
queue<int> q;
int gg(int u) { return ~par[u] ? par[u] = gg(par[u]) : u; }
void merge(int u, int v) {
  u = gg(u);
  v = gg(v);
  if (u == v) return;
  par[v] = u;
}
void upd(int u, int v) {
  if (u > v) swap(u, v);
  int a = gg(u), b = gg(v);
  if (edge.erase({u, v})) {
    if (!--ed[a][b]) ed[a].erase(b);
    if (!--ed[b][a]) ed[b].erase(a);
  } else {
    edge.insert({u, v});
    ed[a][b]++, ed[b][a]++;
  }
}
void bfs(int root, bool st) {
  q.push(root);
  mark[root] = st;
  while (!q.empty()) {
    int u = q.front();
    for (auto v : ed[u])
      if (mark[v.first] ^ st) {
        mark[v.first] = st;
        q.push(v.first);
      }
    q.pop();
  }
}
bool get(int u, int v) {
  bfs(u = gg(u), true);
  bool ans = mark[gg(v)];
  return bfs(u, false), ans;
}
int main() {
  scanf("%d%d", &n, &m);
  while (m) {
    bad.clear();
    m -= (k = min(m, SQ));
    for (int i = 0; i < k; i++) {
      int t, u, v;
      scanf("%d%d%d", &t, &u, &v);
      if (u % n > v % n) swap(u, v);
      bad.insert({u % n, v % n});
      if (u-- > v--) swap(u, v);
      qu[i] = {t, u, v}, bad.insert({u, v});
    }
    memset(par, -1, sizeof par);
    for (int i = 0; i < n; i++) ed[i].clear();
    for (auto x : edge)
      if (!bad.count(x)) merge(x.first, x.second);
    for (auto x : edge)
      if (bad.count(x)) {
        ed[gg(x.first)][gg(x.second)]++;
        ed[gg(x.second)][gg(x.first)]++;
      }
    for (int i = 0; i < k; i++) {
      (qu[i].u += last) %= n;
      (qu[i].v += last) %= n;
      if (qu[i].t & 1)
        upd(qu[i].u, qu[i].v);
      else
        printf("%d", last = get(qu[i].u, qu[i].v));
    }
  }
}
