#include <bits/stdc++.h>
using namespace std;
template <class X, class Y>
bool minimize(X &x, const Y &y) {
  X eps = 1e-9;
  if (x > y + eps) {
    x = y;
    return true;
  } else
    return false;
}
template <class X, class Y>
bool maximize(X &x, const Y &y) {
  X eps = 1e-9;
  if (x + eps < y) {
    x = y;
    return true;
  } else
    return false;
}
template <class T>
T Abs(const T &x) {
  return (x < 0 ? -x : x);
}
bool isSquareFree(int x) {
  for (int i = 2; 1LL * i * i <= x; i++)
    if (x % (i * i) == 0) return false;
  return true;
}
const int MAX_VALUE = 7070;
bitset<MAX_VALUE + 3> single[MAX_VALUE + 3], needCount[MAX_VALUE + 3];
vector<int> squarefree;
void prepare(void) {
  for (int i = (1), _b = (MAX_VALUE); i <= _b; i++)
    if (isSquareFree(i)) squarefree.push_back(i);
  for (int i = (1), _b = (MAX_VALUE); i <= _b; i++)
    for (int j = 1; j * j <= i; j++)
      if (i % j == 0) {
        single[i][j] = 1;
        if (j * j < i) single[i][i / j] = 1;
      }
  for (int i = (1), _b = (MAX_VALUE); i <= _b; i++)
    for (__typeof((squarefree).begin()) jt = (squarefree).begin();
         jt != (squarefree).end(); jt++) {
      if (i * (*jt) > MAX_VALUE) break;
      needCount[i][i * (*jt)] = 1;
    }
}
bitset<MAX_VALUE + 3> sets[100100];
int numSet, numQuery;
void process(void) {
  scanf("%d%d", &numSet, &numQuery);
  for (int love = 0, _n = (numQuery); love < _n; love++) {
    int type, x, y;
    scanf("%d%d%d", &type, &x, &y);
    if (type == 1) {
      sets[x] = single[y];
    }
    if (type == 2) {
      int z;
      scanf("%d", &z);
      sets[x] = sets[y] ^ sets[z];
    }
    if (type == 3) {
      int z;
      scanf("%d", &z);
      sets[x] = sets[y] & sets[z];
    }
    if (type == 4) {
      printf("%d", int((sets[x] & needCount[y]).count() % 2));
    }
  }
  printf("\n");
}
int main(void) {
  prepare();
  process();
  return 0;
}
