#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int M = 2e5 + 5;
const int BS = 450;
int n, m;
int dsu[N];
int find_old(int v) { return dsu[v] < 0 ? v : dsu[v] = find_old(dsu[v]); }
void merge_old(int u, int v) {
  u = find_old(u), v = find_old(v);
  if (u == v) return;
  if (dsu[v] < dsu[u]) swap(u, v);
  dsu[u] += dsu[v];
  dsu[v] = u;
}
stack<pair<int, int> > hist;
int find_cur(int v) { return dsu[v] < 0 ? v : find_cur(dsu[v]); }
void merge_cur(int u, int v) {
  u = find_cur(u), v = find_cur(v);
  if (u == v) return;
  if (dsu[v] < dsu[u]) swap(u, v);
  hist.push({u, dsu[u]});
  hist.push({v, dsu[v]});
  dsu[u] += dsu[v];
  dsu[v] = u;
}
void undo_merges() {
  while (!hist.empty()) {
    int v, d;
    tie(v, d) = hist.top();
    dsu[v] = d;
    hist.pop();
  }
}
struct query {
  int t, x, y;
  int e0, e1;
} q[M];
struct edge {
  int u, v;
  edge(int x = 0, int y = 0) : u(min(x, y)), v(max(x, y)) {}
};
bool operator<(const edge &a, const edge &b) {
  return a.u - b.u ? a.u < b.u : a.v < b.v;
}
edge edges[2 * M];
int edge_cnt;
map<edge, int> eidx;
int get_idx(edge e) {
  if (!eidx.count(e)) {
    edges[edge_cnt] = e;
    eidx[e] = edge_cnt++;
  }
  return eidx[e];
}
bool is_spe[2 * M];
bool is_on[2 * M];
int ans[M];
vector<int> cur;
void init(int l) {
  fill(is_on, is_on + 2 * l, 0);
  for (int i = 0; i < l; i++)
    if (q[i].t == 1) {
      int e = ans[i] ? q[i].e1 : q[i].e0;
      is_on[e] ^= 1;
    }
  int r = min(l + BS, m);
  fill(is_spe, is_spe + 2 * l, 0);
  for (int i = l; i < r; i++)
    if (q[i].t == 1)
      for (int e : {q[i].e0, q[i].e1}) is_spe[e] = 1;
  cur.clear();
  fill(dsu, dsu + N, -1);
  for (int i = 0; i < l; i++)
    if (q[i].t == 1) {
      int e = ans[i] ? q[i].e1 : q[i].e0;
      if (is_on[e]) {
        if (is_spe[e]) {
          cur.push_back(e);
          is_on[e] = 0;
        } else
          merge_old(edges[e].u, edges[e].v);
      }
    }
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  bool lans = 0;
  string res;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> q[i].t >> q[i].x >> q[i].y;
    q[i].x--;
    q[i].y--;
    if (q[i].t == 1) {
      edge e0 = {q[i].x, q[i].y};
      q[i].e0 = get_idx(e0);
      edge e1 = {(q[i].x + 1) % n, (q[i].y + 1) % n};
      q[i].e1 = get_idx(e1);
    }
  }
  for (int i = 0; i < m; i++) {
    ans[i] = lans;
    if (i % BS == 0) init(i);
    if (q[i].t == 1) {
      cur.push_back(ans[i] ? q[i].e1 : q[i].e0);
    } else {
      for (int e : cur) is_on[e] ^= 1;
      for (int e : cur)
        if (is_on[e]) {
          merge_cur(edges[e].u, edges[e].v);
          is_on[e] = 0;
        }
      lans = find_cur((q[i].x + lans) % n) == find_cur((q[i].y + lans) % n);
      res += '0' + lans;
      undo_merges();
    }
  }
  cout << res << '\n';
}
