#include <bits/stdc++.h>
using namespace std;
multiset<int> gd[300005];
int vis[300005];
bool dfs(int x, int y, int vi) {
  if (x == y) {
    return true;
  }
  vis[x] = vi;
  for (int xx : gd[x]) {
    if (vis[xx] != vi) {
      if (dfs(xx, y, vi)) return true;
    }
  }
  return false;
}
class DSU {
 public:
  int p[300005];
  int r[300005];
  DSU(int n) { init(n); }
  void init(int n) {
    for (int i = 0; i <= n + 4; i++) {
      p[i] = i;
      r[i] = 0;
    }
  }
  int par(int x) { return (p[x] == x) ? p[x] : (p[x] = par(p[x])); }
  bool sameComponenet(int a, int b) { return par(a) != par(b); }
  int unite(int a, int b) {
    a = par(a);
    b = par(b);
    if (a == b) return 0;
    if (r[a] > r[b])
      p[b] = a;
    else
      p[a] = b;
    if (r[a] == r[b]) r[b]++;
    return 1;
  }
};
class FForcedOnlineQueriesProblem {
 public:
  void solve(std::istream& cin, std::ostream& cout) {
    int n, k;
    cin >> n >> k;
    DSU d(n);
    int op[k];
    memset(vis, 0, 300005 * sizeof(int));
    pair<int, int> edg[k];
    int erasureTime[k];
    map<pair<int, int>, int> mpe;
    for (int i = 0; i < k; i++) erasureTime[i] = INT_MAX;
    for (int i = 0; i < k; i++) {
      int c;
      cin >> c;
      switch (c) {
        case 1:
          op[i] = 1;
          cin >> edg[i].first >> edg[i].second;
          break;
        case 2:
          op[i] = 2;
          cin >> edg[i].first >> edg[i].second;
          break;
      }
    }
    int last = -1, ct = 1;
    int ans = 0;
    const int blockSize = 4000;
    while (last < k - 1) {
      if (last != -1) d.init(n);
      int cc = n;
      while (last < k - 1 && op[last + 1] != 2) {
        last++;
        int x = (edg[last].first + ans - 1) % n + 1;
        int y = (edg[last].second + ans - 1) % n + 1;
        if (x > y) swap(x, y);
        auto it = mpe.find({x, y});
        if (it != mpe.end()) {
          erasureTime[it->second] = last;
          erasureTime[last] = -1;
          mpe.erase(it);
        } else {
          mpe[{x, y}] = last;
        }
      }
      vector<pair<int, int>> ttp;
      set<pair<int, int>> eds;
      for (auto it : mpe) {
        eds.insert(it.first);
      }
      for (int i = last + 1; i <= min(last + blockSize, k - 1); i++) {
        if (op[i] == 1) {
          int x = edg[i].first;
          int y = edg[i].second;
          if (x > y) swap(x, y);
          auto it = eds.find({x, y});
          if (it != eds.end()) {
            ttp.push_back({x, y});
            eds.erase(it);
          }
          int nx = x % n + 1, ny = y % n + 1;
          if (nx > ny) swap(nx, ny);
          it = eds.find({nx, ny});
          if (it != eds.end()) {
            ttp.push_back({nx, ny});
            eds.erase(it);
          }
        }
      }
      for (pair<int, int> p : eds) d.unite(p.first, p.second);
      for (pair<int, int> x : ttp) {
        int a = d.par(x.first);
        int b = d.par(x.second);
        gd[a].insert(b);
        gd[b].insert(a);
      }
      for (int i = last + 1; i <= min(last + blockSize, k - 1); i++) {
        if (op[i] == 2) {
          int realx = d.par((edg[i].first + ans - 1) % n + 1);
          int realy = d.par((edg[i].second + ans - 1) % n + 1);
          if (dfs(realx, realy, ct)) {
            ans = 1;
          } else
            ans = 0;
          ct++;
          cout << ans;
        } else if (op[i] == 1) {
          int a = (edg[i].first + ans - 1) % n + 1;
          int b = (edg[i].second + ans - 1) % n + 1;
          if (a > b) swap(a, b);
          edg[i] = {a, b};
          auto it = mpe.find(edg[i]);
          if (it == mpe.end()) {
            mpe[edg[i]] = i;
            a = d.par(a);
            b = d.par(b);
            gd[a].insert(b);
            gd[b].insert(a);
          } else {
            erasureTime[it->second] = i;
            erasureTime[i] = -1;
            mpe.erase(it);
            a = d.par(a);
            b = d.par(b);
            gd[a].erase(gd[a].find(b));
            gd[b].erase(gd[b].find(a));
          }
        }
      }
      for (int i = 1; i <= n; i++) gd[i].clear();
      last = min(last + blockSize, k - 1);
    }
    cout << endl;
  }
};
int main() {
  FForcedOnlineQueriesProblem solver;
  std::ios::sync_with_stdio(false);
  std::cin.tie(NULL);
  std::cout.tie(NULL);
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  return 0;
}
