#include <bits/stdc++.h>
using namespace std;
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
inline int gi() {
  int x;
  for (c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++);
       c < '0' || c > '9';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    ;
  for (x = 0; c <= '9' && c >= '0';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    x = (x << 1) + (x << 3) + (c & 15);
  return x;
}
}  // namespace io
using io::gi;
const int N = 2e5 + 5;
struct query {
  int op, x0, y0, x1, y1;
  int vis[2];
  pair<int, int> nxt0, nxt1;
} q[N];
vector<pair<int, int> > st[N << 2];
int n, m, f[N], rk[N], stk[N], tp, lst;
map<pair<int, int>, int> mp;
int mid;
pair<int, int> pre[N << 1];
map<pair<int, int>, int> tim, P;
int findset(int u) { return f[u] ? findset(f[u]) : u; }
void unionset(int u, int v) {
  u = findset(u), v = findset(v);
  if (u != v) {
    if (rk[u] < rk[v]) swap(u, v);
    f[v] = u, rk[u] += rk[v];
    stk[++tp] = v;
  }
}
void update(int x, int l, int r, int sl, int sr, pair<int, int> w) {
  if (sl > sr) return;
  if (sl <= l && r <= sr) {
    st[x].push_back(w);
    return;
  }
  int mid = l + r >> 1;
  if (sl <= mid) update((x << 1), l, mid, sl, sr, w);
  if (sr > mid) update((x << 1 | 1), mid + 1, r, sl, sr, w);
}
void solve(int x, int l, int r) {
  int now = tp;
  for (auto i : st[x]) unionset(i.first, i.second);
  if (l == r) {
    int nu = q[l].x0, nv = q[l].y0, lu = q[l].x1, lv = q[l].y1,
        nvis = q[l].vis[0], lvis = q[l].vis[1], r = 0;
    pair<int, int> nnxt = q[l].nxt0, lnxt = q[l].nxt1;
    if (q[l].op == 2) {
      if (lst)
        swap(nu, lu), swap(nv, lv), swap(nvis, lvis), swap(nnxt, lnxt), r = 1;
      printf("%d", lst = (findset(nu) == findset(nv)));
    } else {
      if (nu == lu && lv == nv) {
        if (tim[make_pair(nu, nv)] % 2 == 0) {
          update(1, 1, m, l + 1, nnxt.first - 1, make_pair(nu, nv));
        }
        tim[make_pair(nu, nv)]++;
      } else {
        if (lst == 0) {
          tim[make_pair(nu, nv)]++;
          if (tim[make_pair(nu, nv)] % 2 == 1) {
            update(1, 1, m, l + 1, nnxt.first - 1, make_pair(nu, nv));
          }
          if (tim[make_pair(lu, lv)] % 2 == 1) {
            update(1, 1, m, l + 1, lnxt.first - 1, make_pair(lu, lv));
          }
        }
        if (lst == 1) {
          tim[make_pair(lu, lv)]++;
          if (tim[make_pair(nu, nv)] % 2 == 1) {
            update(1, 1, m, l + 1, nnxt.first - 1, make_pair(nu, nv));
          }
          if (tim[make_pair(lu, lv)] % 2 == 1) {
            update(1, 1, m, l + 1, lnxt.first - 1, make_pair(lu, lv));
          }
        }
      }
    }
  } else {
    int mid = l + r >> 1;
    solve((x << 1), l, mid), solve((x << 1 | 1), mid + 1, r);
  }
  for (; tp > now; --tp) rk[f[stk[tp]]] -= rk[stk[tp]], f[stk[tp]] = 0;
}
int main() {
  n = gi(), m = gi();
  for (int i = 1; i <= n; ++i) rk[i] = 1;
  for (int i = 1; i <= m; ++i) {
    q[i].op = gi(), q[i].x0 = gi(), q[i].y0 = gi();
    if (q[i].x0 > q[i].y0) swap(q[i].x0, q[i].y0);
    q[i].x1 = q[i].x0 % n + 1, q[i].y1 = q[i].y0 % n + 1;
    if (q[i].x1 > q[i].y1) swap(q[i].x1, q[i].y1);
  }
  for (int i = m; i; --i) {
    if (q[i].op == 2) continue;
    int tid = mp[make_pair(q[i].x0, q[i].y0)];
    if (!tid)
      q[i].nxt0 = make_pair(m + 1, 0),
      tid = mp[make_pair(q[i].x0, q[i].y0)] = ++mid;
    else
      q[i].nxt0 = pre[tid];
    pre[tid] = make_pair(i, 0);
    tid = mp[make_pair(q[i].x1, q[i].y1)];
    if (!tid)
      q[i].nxt1 = make_pair(m + 1, 0),
      tid = mp[make_pair(q[i].x1, q[i].y1)] = ++mid;
    else
      q[i].nxt1 = pre[tid];
    pre[tid] = make_pair(i, 1);
  }
  tim.clear();
  P.clear();
  solve(1, 1, m);
}
