#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define rep(i,l,r) for(rint i=l;i<=r;i++)
#define per(i,l,r) for(rint i=l;i>=r;i--)
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define fir first
#define sec second
#define mset(s,t) memset(s,t,sizeof(s))
template<typename T1,typename T2>void ckmin(T1 &a,T2 b){if(a>b)a=b;}
template<typename T1,typename T2>void ckmax(T1 &a,T2 b){if(a<b)a=b;}
template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
int read(){
  int x=0,f=0;
  char ch=getchar();
  while(!isdigit(ch))f|=ch=='-',ch=getchar();
  while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
  return f?-x:x;
}
const int N=100005;
int mu[N],n,q;
vector<int>pr;
bool vis[N];
bitset<7001>a[N],g[7005],ys[7005];
void init(int n){
  mu[1]=1;
  for(int i=2;i<=n;i++){
    if(!vis[i])pr.pb(i),mu[i]=1;
    for(auto v:pr){
      if(i*v>n)break;
      vis[i*v]=1;
      if(i%v==0)break;
      mu[i*v]=1;
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j+=i){
      if(mu[j/i])g[i].set(j);
      ys[j].set(i);
    }
  }
}
int main(){
  init(7000);
  n=read(),q=read();
  while(q--){
    int opt=read(),x=read(),y=read();
    if(opt==1){
      a[x]=ys[y];
    }else if(opt==2){
      int z=read();
      a[x]=a[y]^a[z];
    }else if(opt==3){
      int z=read();
      a[x]=a[y]&a[z];
    }else{
      int cnt=(a[x]&g[y]).count()&1;
      putchar(cnt?'1':'0');
    }
  }
  return 0;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define rep(i,l,r) for(rint i=l;i<=r;i++)
#define per(i,l,r) for(rint i=l;i>=r;i--)
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define fir first
#define sec second
#define mset(s,t) memset(s,t,sizeof(s))
template<typename T1,typename T2>void ckmin(T1 &a,T2 b){if(a>b)a=b;}
template<typename T1,typename T2>void ckmax(T1 &a,T2 b){if(a<b)a=b;}
template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
int read(){
  int x=0,f=0;
  char ch=getchar();
  while(!isdigit(ch))f|=ch=='-',ch=getchar();
  while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
  return f?-x:x;
}
const int N=100005;
int mu[N],n,q;
vector<int>pr;
bool vis[N];
bitset<7001>a[N],g[7005],ys[7005];
void init(int n){
  mu[1]=1;
  for(int i=2;i<=n;i++){
    if(!vis[i])pr.pb(i),mu[i]=1;
    for(auto v:pr){
      if(i*v>n)break;
      vis[i*v]=1;
      if(i%v==0)break;
      mu[i*v]=mu[i];
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j+=i){
      if(mu[j/i])g[i].set(j);
      ys[j].set(i);
    }
  }
}
int main(){
  init(7000);
  n=read(),q=read();
  while(q--){
    int opt=read(),x=read(),y=read();
    if(opt==1){
      a[x]=ys[y];
    }else if(opt==2){
      int z=read();
      a[x]=a[y]^a[z];
    }else if(opt==3){
      int z=read();
      a[x]=a[y]&a[z];
    }else{
      int cnt=(a[x]&g[y]).count();
      putchar(cnt%2?'1':'0');
    }
  }
  return 0;
}


#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template<typename T, class _bset_array, int MX, int B>
struct precomputation {
	static constexpr array<_bset_array, MX+1> compute_init() {
		array<_bset_array, MX+1> init{};
		for(int i = 1; i <= MX; i++)
			for(int j = 1; j <= MX/i; j++)
				init[j*i][i/B] ^= static_cast<T>(1) << (i & (B-1));
		return init;
	}

	static constexpr array<_bset_array, MX+1> compute_coef() {
		array<_bset_array, MX+1> coef{};
		for(int i = 1; i <= MX; i++) {
			bool is_squarefree = true;
			for(int j = 2; j*j <= i; j++)
				is_squarefree &= (i % (j * j) != 0);
			if(is_squarefree)
				for(int j = 1; j <= MX/i; j++)
					coef[j][(i*j)/B] ^= static_cast<T>(1) << ((i*j) & (B-1));
		}
		return coef;
	}
};

class bset {
	static constexpr int MX = 7000, B = 64;
	using T = uint64_t;
	using _bset = array<T, MX/B+1>;

	static constexpr auto _init = precomputation<T, _bset, MX, B>::compute_init();
	static constexpr auto _coef = precomputation<T, _bset, MX, B>::compute_coef();

	_bset a{};

public:
	void set(int v) {
		a = _init[v];
	}

	bset & operator+=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] ^= V[i];
		return *this;
	}

	void set_sum(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] ^ W[i];
	}

	bset & operator*=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] &= V[i];
		return *this;
	}

	void set_prod(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] & W[i];
	}

	inline T operator[](size_t i) const {
		return a[i];
	}

	bool find(int v) const {
		T x = 0;
		for(int i = 0; i <= MX/B; i++) x ^= (_coef[v][i] & a[i]);
		bool ret = 0;
		while(x) {
			ret ^= x&1;
			x /= 2;
		}
		return x;
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, Q;
	cin >> N >> Q;
	vector<bset> S(N+1);
	for(int i = 0; i < Q; i++) {
		int type, x, y, z, v;
		cin >> type;
		if(type == 1) {
			cin >> x >> v;
			S[x].set(v);
		}
		else if(type == 2) {
			cin >> x >> y >> z;
			S[x].set_sum(S[y], S[z]);
		}
		else if(type == 3) {
			cin >> x >> y >> z;
			S[x].set_prod(S[y], S[z]);
		}
		else if(type == 4) {
			cin >> x >> v;
			cout << S[x].find(v);
		}
	}
	cout << "\n";
	return 0;
}

// look at my code
// my code is amazing


#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template<typename T, class _bset_array, int MX, int B>
struct precomputation {
	static constexpr array<_bset_array, MX+1> compute_init() {
		array<_bset_array, MX+1> init{};
		for(int i = 1; i <= MX; i++)
			for(int j = 1; j <= MX/i; j++)
				init[j*i][i/B] ^= static_cast<T>(1) << (i & (B-1));
		return init;
	}

	static constexpr array<_bset_array, MX+1> compute_coef() {
		array<_bset_array, MX+1> coef{};
		for(int i = 1; i <= MX; i++) {
			bool is_squarefree = true;
			for(int j = 2; j*j <= i; j++)
				is_squarefree &= (i % (j * j) != 0);
			if(is_squarefree)
				for(int j = 1; j <= MX/i; j++)
					coef[j][(i*j)/B] ^= static_cast<T>(1) << ((i*j) & (B-1));
		}
		return coef;
	}
};

class bset {
	static constexpr int MX = 7000, B = 64;
	using T = uint64_t;
	using _bset = array<T, MX/B+1>;

	static constexpr auto _init = precomputation<T, _bset, MX, B>::compute_init();
	static constexpr auto _coef = precomputation<T, _bset, MX, B>::compute_coef();

	_bset a{};

public:
	void clear() {
		a.fill(0);
	}

	void set(int v) {
		a = _init[v];
	}

	bset & operator+=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] ^= V[i];
		return *this;
	}

	void set_sum(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] ^ W[i];
	}

	bset & operator*=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] &= V[i];
		return *this;
	}

	void set_prod(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] & W[i];
	}

	inline T operator[](size_t i) const {
		return a[i];
	}

	bool find(int v) const {
		T ret = false;
		for(int i = 0; i <= MX/B; i++) ret ^= (_coef[v][i] & a[i]);
		return __builtin_popcount(ret) & 1;
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, Q;
	cin >> N >> Q;
	vector<bset> S(N+1);
	for(int i = 0; i < Q; i++) {
		int type, x, y, z, v;
		cin >> type;
		if(type == 1) {
			cin >> x >> v;
			S[x].set(v);
		}
		else if(type == 2) {
			cin >> x >> y >> z;
			if(x == z) swap(y, z);
			if(y == z) S[x].clear();
			else if(x == y) S[x] += S[z];
			else S[x].set_sum(S[y], S[z]);
		}
		else if(type == 3) {
			cin >> x >> y >> z;
			if(x == z) swap(y, z);
			if(x == y) S[x] *= S[z];
			else S[x].set_prod(S[y], S[z]);
		}
		else if(type == 4) {
			cin >> x >> v;
			cout << S[x].find(v);
		}
	}
	cout << "\n";
	return 0;
}

// look at my code
// my code is amazing


#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template<typename T, class _bset_array, int MX, int B>
struct precomputation {
	static constexpr array<_bset_array, MX+1> compute_init() {
		array<_bset_array, MX+1> init{};
		for(int i = 1; i <= MX; i++)
			for(int j = 1; j <= MX/i; j++)
				init[j*i][i/B] ^= static_cast<T>(1) << (i & (B-1));
		return init;
	}

	static constexpr array<_bset_array, MX+1> compute_coef() {
		array<_bset_array, MX+1> coef{};
		for(int i = 1; i <= MX; i++) {
			bool is_squarefree = true;
			for(int j = 2; j*j <= i; j++)
				is_squarefree &= (i % (j * j) != 0);
			if(is_squarefree)
				for(int j = 1; j <= MX/i; j++)
					coef[j][(i*j)/B] ^= static_cast<T>(1) << ((i*j) & (B-1));
		}
		return coef;
	}
};

class bset {
	static constexpr int MX = 7000, B = 64;
	using T = uint64_t;
	using _bset = array<T, MX/B+1>;

	static constexpr auto _init = precomputation<T, _bset, MX, B>::compute_init();
	static constexpr auto _coef = precomputation<T, _bset, MX, B>::compute_coef();

	_bset a{};

public:
	void set(int v) {
		a = _init[v];
	}

	bset & operator+=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] ^= V[i];
		return *this;
	}

	void set_sum(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] ^ W[i];
	}

	bset & operator*=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] &= V[i];
		return *this;
	}

	void set_prod(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] & W[i];
	}

	inline T operator[](size_t i) const {
		return a[i];
	}

	bool find(int v) const {
		T ret = 0;
		for(int i = 0; i <= MX/B; i++) ret ^= (_coef[v][i] & a[i]);
		return __builtin_popcount(ret) & 1;
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, Q;
	cin >> N >> Q;
	vector<bset> S(N+1);
	for(int i = 0; i < Q; i++) {
		int type, x, y, z, v;
		cin >> type;
		if(type == 1) {
			cin >> x >> v;
			S[x].set(v);
		}
		else if(type == 2) {
			cin >> x >> y >> z;
			S[x].set_sum(S[y], S[z]);
		}
		else if(type == 3) {
			cin >> x >> y >> z;
			S[x].set_prod(S[y], S[z]);
		}
		else if(type == 4) {
			cin >> x >> v;
			cout << S[x].find(v);
		}
	}
	cout << "\n";
	return 0;
}

// look at my code
// my code is amazing


#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template<typename T, class _bset_array, int MX, int B>
struct precomputation {
	static constexpr array<_bset_array, MX+1> compute_init() {
		array<_bset_array, MX+1> init{};
		for(int i = 1; i <= MX; i++)
			for(int j = 1; j <= MX/i; j++)
				init[j*i][i/B] ^= static_cast<T>(1) << (i & (B-1));
		return init;
	}

	static constexpr array<_bset_array, MX+1> compute_coef() {
		array<_bset_array, MX+1> coef{};
		for(int i = 1; i <= MX; i++) {
			bool is_squarefree = true;
			for(int j = 2; j*j <= i; j++)
				is_squarefree &= (i % (j * j) != 0);
			if(is_squarefree)
				for(int j = 1; j <= MX/i; j++)
					coef[j][(i*j)/B] ^= static_cast<T>(1) << ((i*j) & (B-1));
		}
		return coef;
	}
};

class bset {
	static constexpr int MX = 7000, B = 64;
	using T = uint64_t;
	using _bset = array<T, MX/B+1>;

	static constexpr auto _init = precomputation<T, _bset, MX, B>::compute_init();
	static constexpr auto _coef = precomputation<T, _bset, MX, B>::compute_coef();

	_bset a{};

public:
	void set(int v) {
		a = _init[v];
	}

	bset & operator+=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] ^= V[i];
		return *this;
	}

	void set_sum(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] ^ W[i];
	}

	bset & operator*=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] &= V[i];
		return *this;
	}

	void set_prod(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] & W[i];
	}

	inline T operator[](size_t i) const {
		return a[i];
	}

	bool find(int v) const {
		T x = 0;
		for(int i = 0; i <= MX/B; i++) x ^= (_coef[v][i] & a[i]);
		bool ret = false;
		while(x > 0) {
			ret ^= x & 1;
			x /= 2;
		}
		return ret;
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, Q;
	cin >> N >> Q;
	vector<bset> S(N+1);
	for(int i = 0; i < Q; i++) {
		int type, x, y, z, v;
		cin >> type;
		if(type == 1) {
			cin >> x >> v;
			S[x].set(v);
		}
		else if(type == 2) {
			cin >> x >> y >> z;
			S[x].set_sum(S[y], S[z]);
		}
		else if(type == 3) {
			cin >> x >> y >> z;
			S[x].set_prod(S[y], S[z]);
		}
		else if(type == 4) {
			cin >> x >> v;
			cout << S[x].find(v);
		}
	}
	cout << "\n";
	return 0;
}

// look at my code
// my code is amazing


#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template<typename T, class _bset_array, int MX, int B>
struct precomputation {
	static constexpr array<_bset_array, MX+1> compute_init() {
		array<_bset_array, MX+1> init{};
		for(int i = 0; i <= MX; i++) for(int j = 0; j <= MX/B; j++) assert(init[i][j] == 0);
		for(int i = 1; i <= MX; i++)
			for(int j = 1; j <= MX/i; j++)
				init[j*i][i/B] ^= static_cast<T>(1) << (i & (B-1));
		return init;
	}

	static constexpr array<_bset_array, MX+1> compute_coef() {
		array<_bset_array, MX+1> coef{};
		for(int i = 0; i <= MX; i++) for(int j = 0; j <= MX/B; j++) assert(coef[i][j] == 0);
		for(int i = 1; i <= MX; i++) {
			bool is_squarefree = true;
			for(int j = 2; j*j <= i; j++)
				is_squarefree &= (i % (j * j) != 0);
			if(is_squarefree)
				for(int j = 1; j <= MX/i; j++)
					coef[j][(i*j)/B] ^= static_cast<T>(1) << ((i*j) & (B-1));
		}
		return coef;
	}
};

class bset {
	static constexpr int MX = 7000, B = 64;
	using T = uint64_t;
	using _bset = array<T, MX/B+1>;

	static constexpr auto _init = precomputation<T, _bset, MX, B>::compute_init();
	static constexpr auto _coef = precomputation<T, _bset, MX, B>::compute_coef();

	_bset a{};

public:
	void set(int v) {
		a = _init[v];
	}

	bset & operator+=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] ^= V[i];
		return *this;
	}

	void set_sum(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] ^ W[i];
	}

	bset & operator*=(const bset & V) {
		for(int i = 0; i <= MX/B; i++) a[i] &= V[i];
		return *this;
	}

	void set_prod(const bset & V, const bset & W) {
		for(int i = 0; i <= MX/B; i++) a[i] = V[i] & W[i];
	}

	inline T operator[](size_t i) const {
		return a[i];
	}

	bool find(int v) const {
		T ret = 0;
		for(int i = 0; i <= MX/B; i++) ret ^= (_coef[v][i] & a[i]);
		return __builtin_popcount(ret) & 1;
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N, Q;
	cin >> N >> Q;
	vector<bset> S(N+1);
	for(int i = 0; i < Q; i++) {
		int type, x, y, z, v;
		cin >> type;
		if(type == 1) {
			cin >> x >> v;
			S[x].set(v);
		}
		else if(type == 2) {
			cin >> x >> y >> z;
			S[x].set_sum(S[y], S[z]);
		}
		else if(type == 3) {
			cin >> x >> y >> z;
			S[x].set_prod(S[y], S[z]);
		}
		else if(type == 4) {
			cin >> x >> v;
			cout << S[x].find(v);
		}
	}
	cout << "\n";
	return 0;
}

// look at my code
// my code is amazing


#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;

const int N = 100005, MX = 7001;

int n, q, t, x, y, z, v;
bool chk[N];
bitset<MX> cur, f[MX], g[MX], bi[N];

void init()
{
    for (int i = 1; i < MX; i++)
        for (int j = 1; j <= i; j++)
            if (i % j == 0)
                f[i].set(j);
    chk[1] = true;
    for (int i = 2; i < MX; i++)
        for (int j = 1; j < i; j++)
            if (i % j == 0)
                chk[i] ^= chk[j];
    for (int i = 1; i < MX; i++)
        for (int j = i; j < MX; j += i)
            if (chk[j / i])
                g[i].set(j);
}

int main()
{
    init();
    scanf("%d%d", &n, &q);
    while (q--)
    {
        scanf("%d", &t);
        if (t == 1)
        {
            scanf("%d%d", &x, &v);
            bi[x] = f[v];
        }
        else if (t == 2)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] ^ bi[z];
        }
        else if (t == 3)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] & bi[z];
        }
        else
        {
            scanf("%d%d", &x, &v);
            cur = bi[x] & g[v];
            printf("%d", cur.count() & 1);
        }
    }
}


#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;

const int N = 100005, MX = 10;

int n, q, t, x, y, z, v;
bool chk[N];
bitset<MX> cur, f[MX], g[MX], bi[N];

void init()
{
    for (int i = 1; i < MX; i++)
        for (int j = 1; j <= i; j++)
            if (i % j == 0)
                f[i].set(j);
    chk[1] = true;
    for (int i = 2; i < MX; i++)
    {
        cur.reset();
        cur.set(i);
        for (int j = MX - 1; j > 1; j--)
            if (cur.test(j))
                cur ^= f[j];
        chk[i] = cur.test(1);
    }
    for (int i = 1; i < MX; i++)
        for (int j = i; j < MX; j += i)
            if (chk[j / i])
                g[i].set(j);
}

int main()
{
    init();
    scanf("%d%d", &n, &q);
    while (q--)
    {
        scanf("%d", &t);
        if (t == 1)
        {
            scanf("%d%d", &x, &v);
            bi[x] = f[v];
        }
        else if (t == 2)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] ^ bi[z];
        }
        else if (t == 3)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] & bi[z];
        }
        else
        {
            scanf("%d%d", &x, &v);
            cur = bi[x];
            for (int i = MX - 1; i > v; i--)
                if (cur.test(i))
                    cur ^= f[i];
            printf("%d", cur.test(v));
        }
    }
}


#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;

const int N = 100005, MX = 10;

int n, q, t, x, y, z, v;
bool chk[N];
bitset<MX> cur, f[MX], g[MX], bi[N];

void init()
{
    for (int i = 1; i < MX; i++)
        for (int j = 1; j <= i; j++)
            if (i % j == 0)
                f[i].set(j);
    chk[1] = true;
    for (int i = 2; i < MX; i++)
    {
        cur.reset();
        cur.set(i);
        for (int j = MX - 1; j > 1; j--)
            if (cur.test(j))
                cur ^= f[j];
        chk[i] = cur.test(1);
    }
    for (int i = 1; i < MX; i++)
        for (int j = i; j < MX; j += i)
            if (chk[j / i])
                g[i].set(j);
}

int main()
{
    init();
    scanf("%d%d", &n, &q);
    while (q--)
    {
        scanf("%d", &t);
        if (t == 1)
        {
            scanf("%d%d", &x, &v);
            bi[x] = f[v];
        }
        else if (t == 2)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] ^ bi[z];
        }
        else if (t == 3)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] & bi[z];
        }
        else
        {
            scanf("%d%d", &x, &v);
            cur = bi[x] & g[v];
            printf("%d", cur.count() & 1);
        }
    }
}


#include <iostream>
#include <cstdio>
#include <bitset>
using namespace std;

const int N = 100005, MX = 7001;

int n, q, t, x, y, z, v;
bool chk[N];
bitset<MX> cur, f[MX], g[MX], bi[N];

void init()
{
    for (int i = 1; i < MX; i++)
        for (int j = 1; j <= i; j++)
            if (i % j == 0)
                f[i].set(j);
    chk[1] = true;
    for (int i = 2; i < MX; i++)
    {
        cur.reset();
        cur.set(i);
        for (int j = MX - 1; j > 1; j--)
            if (cur.test(j))
                cur ^= f[j];
        chk[i] = cur.test(1);
    }
    for (int i = 1; i < MX; i++)
        for (int j = i; j < MX; j += i)
            if (chk[j / i])
                g[i].set(j);
}

int main()
{
    init();
    scanf("%d%d", &n, &q);
    while (q--)
    {
        scanf("%d", &t);
        if (t == 1)
        {
            scanf("%d%d", &x, &v);
            bi[x] = f[v];
        }
        else if (t == 2)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] ^ bi[z];
        }
        else if (t == 3)
        {
            scanf("%d%d%d", &x, &y, &z);
            bi[x] = bi[y] & bi[z];
        }
        else
        {
            scanf("%d%d", &x, &v);
            cur = bi[x] & g[v];
            printf("%d", cur.count() & 1);
        }
    }
}


#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long double, long double > pdd;
typedef pair< long long, long long > pll;

const int inf = 1e9;
const ll inf64 = 1e18;

const int X = 7001;
const int N = 1e5 + 5;

int n, q;
bitset< X > bs[N];
bitset< X > up[X];
short dp[X][X];

bitset< X > gcd(bitset< X > a, bitset< X > bb) {
    if(a.count() > bb.count()) swap(a, bb);
    bitset< X > res;
    while(a.any()) {
        int i = a._Find_first();
        bitset< X > b = bb;
        while(b.any()) {
            int j = b._Find_first();
            int k = dp[i][j];
            if((up[j] & b).count() & 1) {
                res[k] = res[k] ^ 1;
            }
            b &= ~up[j];
        }
        a[i] = 0;
    }
    return res;
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    for(int x = 0;x < X;x++) {
        for(int y = 0;y < X;y++) {
            if(!x) {
                dp[x][y] = y;
                continue;
            }
            if(!y) {
                dp[x][y] = x;
                continue;
            }
            if(x > y) {
                dp[x][y] = dp[x - y][y];
            }else {
                dp[x][y] = dp[x][y - x];
            }
        }
    }

    for(int x = 1;x < X;x++) {
        for(int y = x;y < X;y += x) {
            up[x][y] = 1;
        }
    }

    scanf("%d %d", &n, &q);

    for(int iter = 0;iter < q;iter++) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int x, v;
            scanf("%d %d", &x, &v);
            bs[x].reset();
            bs[x][v] = 1;
        }else if(type == 2) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] ^ bs[z];
        }else if(type == 3) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = gcd(bs[y], bs[z]);
        }else if(type == 4) {
            int x, v;
            scanf("%d %d", &x, &v);
            printf("%d", (int)bs[x][v]);
        }
    }

    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long double, long double > pdd;
typedef pair< long long, long long > pll;

const int inf = 1e9;
const ll inf64 = 1e18;

const int X = 7001;
const int N = 1e5 + 5;

bitset< X > bs[N];
bitset< X > mu[X];
bitset< X > ff[X];

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    for(int d = X - 1;d >= 1;d--) {
        mu[d][d] = 1;
        for(int k = 2 * d;k < X;k += d) {
            mu[d] ^= mu[k];
        }
    }

    for(int i = 1;i < X;i++) {
        for(int j = i;j < X;j += i) {
            ff[j][i] = 1;
        }
    }

    int n, q;

    scanf("%d %d", &n, &q);

    for(int iter = 0;iter < q;iter++) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int x, v;
            scanf("%d %d", &x, &v);
            bs[x] = ff[v];
        }else if(type == 2) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] ^ bs[z];
        }else if(type == 3) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] & bs[z];
        }else if(type == 4) {
            int x, v;
            scanf("%d %d", &x, &v);
            printf("%d", int( (bs[x] & mu[v]).count() & 1 ));
        }
    }

    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long double, long double > pdd;
typedef pair< long long, long long > pll;

const int inf = 1e9;
const ll inf64 = 1e18;

const int X = 7001;
const int N = 1e5 + 5;

int n, q;
bitset< X > bs[N];
bitset< X > up[X];
int dp[X][X];

bitset< X > gcd(bitset< X > a, bitset< X > bb) {
    if(a.count() > bb.count()) swap(a, bb);
    bitset< X > res;
    while(a.any()) {
        int i = a._Find_first();
        bitset< X > b = bb;
        while(b.any()) {
            int j = b._Find_first();
            int k = dp[i][j];
            if((up[j] & b).count() & 1) {
                res[k] = res[k] ^ 1;
            }
            b &= ~up[j];
        }
        a[i] = 0;
    }
    return res;
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    for(int x = 0;x < X;x++) {
        for(int y = 0;y < X;y++) {
            if(!x) {
                dp[x][y] = y;
                continue;
            }
            if(!y) {
                dp[x][y] = x;
                continue;
            }
            if(x > y) {
                dp[x][y] = dp[x - y][y];
            }else {
                dp[x][y] = dp[x][y - x];
            }
        }
    }

    for(int x = 1;x < X;x++) {
        for(int y = x;y < X;y += x) {
            up[x][y] = 1;
        }
    }

    scanf("%d %d", &n, &q);

    for(int iter = 0;iter < q;iter++) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int x, v;
            scanf("%d %d", &x, &v);
            bs[x].reset();
            bs[x][v] = 1;
        }else if(type == 2) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] ^ bs[z];
        }else if(type == 3) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = gcd(bs[y], bs[z]);
        }else if(type == 4) {
            int x, v;
            scanf("%d %d", &x, &v);
            printf("%d", (int)bs[x][v]);
        }
    }

    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long double, long double > pdd;
typedef pair< long long, long long > pll;

const int inf = 1e9;
const ll inf64 = 1e18;

const int X = 7001;
const int N = 1e5 + 5;

int n, q;
bitset< X > bs[N];
bitset< X > up[N];

bitset< X > gcd(bitset< X > a, bitset< X > bb) {
    if(a.count() > bb.count()) swap(a, bb);
    bitset< X > res;
    while(a.any()) {
        int i = a._Find_first();
        bitset< X > b = bb;
        while(b.any()) {
            int j = b._Find_first();
            int k = __gcd(i, j);
            bitset< X > tmp = up[i] << j;
            if((b & tmp).count() & 1) {
                res[k] = res[k] ^ 1;
            }
            b &= ~tmp;
        }
        a[i] = 0;
    }
    return res;
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    for(int x = 1;x < X;x++) {
        for(int y = 0;y < X;y += x) {
            up[x][y] = 1;
        }
    }

    scanf("%d %d", &n, &q);

    for(int iter = 0;iter < q;iter++) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int x, v;
            scanf("%d %d", &x, &v);
            bs[x].reset();
            bs[x][v] = 1;
        }else if(type == 2) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] ^ bs[z];
        }else if(type == 3) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = gcd(bs[y], bs[z]);
        }else if(type == 4) {
            int x, v;
            scanf("%d %d", &x, &v);
            printf("%d", (int)bs[x][v]);
        }
    }

    printf("\n");

    return 0;
}


#include <bits/stdc++.h>

// pbds
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
// gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair< int, int > pii;
typedef pair< long double, long double > pdd;
typedef pair< long long, long long > pll;

const int inf = 1e9;
const ll inf64 = 1e18;

const int X = 7001;
const int N = 1e5 + 5;

int n, q;
bitset< X > bs[N];
bitset< X > up[X];

bitset< X > gcd(bitset< X > a, bitset< X > bb) {
    if(a.count() > bb.count()) swap(a, bb);
    bitset< X > res;
    while(a.any()) {
        int i = a._Find_first();
        bitset< X > b = bb;
        while(b.any()) {
            int j = b._Find_first();
            int k = __gcd(i, j);
            res[k] = res[k] ^ 1;
            b[j] = 0;
//            if((up[j] & b).count() & 1) {
//                res[k] = res[k] ^ 1;
//            }
//            b &= ~up[j];
        }
        a[i] = 0;
    }
    return res;
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    for(int x = 1;x < X;x++) {
        for(int y = x;y < X;y += x) {
            up[x][y] = 1;
        }
    }

    scanf("%d %d", &n, &q);

    for(int iter = 0;iter < q;iter++) {
        int type;
        scanf("%d", &type);
        if(type == 1) {
            int x, v;
            scanf("%d %d", &x, &v);
            bs[x].reset();
            bs[x][v] = 1;
        }else if(type == 2) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = bs[y] ^ bs[z];
        }else if(type == 3) {
            int x, y, z;
            scanf("%d %d %d", &x, &y, &z);
            bs[x] = gcd(bs[y], bs[z]);
        }else if(type == 4) {
            int x, v;
            scanf("%d %d", &x, &v);
            printf("%d", (int)bs[x][v]);
        }
    }

    printf("\n");

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
#include <complex>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <iomanip>
#include <ctime>
//#include <unordered_map>
#define y1 blablabla
#define ll long long
#define tm ghfdskjdhf
#define MAXN 500005
#define MAXC 7000
//#define INF "~"
#define ss second
#define ff first
#define int long long
#define fpos fuuuu
//#define double long double

using namespace std;

const int w = 60, sz = (7000 + 59) / 60, md = 1 << 20, msk = md - 1;

int n, q, i, j, cnt[(1 << 20) + 5], num[MAXC + 5], pos[MAXC + 5];
vector <int> b[MAXN], c[MAXC + 5], d[MAXC + 5];
bool flag[MAXC + 5];

int get(int x){
    return cnt[x & msk] + cnt[(x >> 20) & msk] + cnt[x >> 40];
}

main(){
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie();

    scanf("%d%d", &n, &q);

    //cout << n << " " << q << endl;
    for(i = 1; i <= MAXC; i++){
        for(j = 1; j * i <= MAXC; j++){
            d[j * i].push_back(i);

            if(j % i == 0 && i != 1)
                flag[i * j] = 1;
        }

        num[i] = i / w; pos[i] = i % w;
    }

    for(i = 1; i <= MAXC; i++){
        c[i].resize(sz);

        for(j = 1; i * j <= MAXC; j++)
            c[i][(i * j) / w] |= (1 - flag[j]) * (1LL << ((i * j) % w));
    }

    for(i = 0; i < (1 << 20); i++)
        cnt[i] = cnt[i >> 1] + (i & 1);

    for(i = 0; i < n; i++)
        b[i].resize(sz);

    while(q--){
        int x, y, z, v, type;

        scanf("%I64d", &type);

        //cout << type << endl;
        if(type == 1){
            scanf("%d%d", &x, &v);
            x--;

            b[x].resize(0);
            b[x].resize(sz);

            for(i = 0; i < d[v].size(); i++)
                b[x][num[d[v][i]]] |= 1LL << pos[d[v][i]];
        }

        if(type == 2){
            scanf("%d%d%d", &x, &y, &z);
            x--; y--; z--;

            for(i = 0; i < sz; i++)
                b[x][i] = b[y][i] ^ b[z][i];
        }

        if(type == 3){
            scanf("%d%d%d", &x, &y, &z);
            x--; y--; z--;

            for(i = 0; i < sz; i++)
                b[x][i] = b[y][i] & b[z][i];
        }

        if(type == 4){
            scanf("%d%d", &x, &v); x--;

            int ans = 0;

            for(i = 0; i < sz; i++)
                ans += get(b[x][i] & c[v][i]);

            printf("%d", ans & 1);
        }
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
#include <complex>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <iomanip>
#include <ctime>
//#include <unordered_map>
#define y1 blablabla
#define ll long long
#define tm ghfdskjdhf
#define MAXN 500005
#define MAXC 7000
//#define INF "~"
#define ss second
#define ff first
#define int long long
#define fpos fuuuu
//#define double long double

using namespace std;

const int w = 60, sz = (7000 + 59) / 60;

int n, q, i, j, cnt[(1 << 20) + 5];
vector <int> b[MAXN], c[MAXC + 5], d[MAXC + 5];
bool flag[MAXC + 5];

int get(int x){
    int md = 1 << 20;
    return cnt[x % md] + cnt[(x / md) % md] + cnt[(x / md) / md];
}

main(){
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie();

    cin >> n >> q;

    for(i = 1; i <= MAXC; i++){
        for(j = 1; j * i <= MAXC; j++){
            d[j * i].push_back(i);

            if(j % i == 0 && i != 1)
                flag[i * j] = 1;
        }
    }

    for(i = 1; i <= MAXC; i++){
        c[i].resize(sz);

        for(j = 1; i * j <= MAXC; j++)
            c[i][(i * j) / w] |= (1 - flag[j]) * (1LL << ((i * j) % w));
    }

    for(i = 0; i < (1 << 20); i++)
        cnt[i] = cnt[i / 2] + i % 2;

    for(i = 0; i < n; i++)
        b[i].resize(sz);

    while(q--){
        int x, y, z, v, type;

        cin >> type;

        if(type == 1){
            cin >> x >> v;
            x--;

            b[x].resize(0);
            b[x].resize(sz);

            for(i = 0; i < d[v].size(); i++)
                b[x][d[v][i] / w] |= 1LL << (d[v][i] % w);// cout <<"(" <<v << " " << d[v][i] << ")" << endl;

            //cout << "!" << x << " " <<  b[x][0] << endl;
        }

        if(type == 2){
            cin >> x >> y >> z;
            x--; y--; z--;

            for(i = 0; i < sz; i++)
                b[x][i] = b[y][i] ^ b[z][i];

            //cout << "!" << x << " " <<  b[x][0] << endl;
        }

        if(type == 3){
            cin >> x >> y >> z;
            x--; y--; z--;

            for(i = 0; i < sz; i++)
                b[x][i] = b[y][i] & b[z][i];

            //cout << "!" << x << " " <<  b[x][0] << endl;
        }

        if(type == 4){
            cin >> x >> v; x--;

            int ans = 0;

            //cout << 123 << endl;
            //cout << b[x].size() << " " << c[v].size() << endl;
            for(i = 0; i < sz; i++)
                ans += get(b[x][i] & c[v][i]);
            //cout << 125 << endl;
            //cout <<"#"<< x << " " << v  << " " << b[x][0] << " " << c[v][0] << endl;
            //cout << "*" << ans << ">";
            cout << ans % 2;
        }
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

vector<vector<int>> divs_all(int x){
	vector<vector<int>> res(x+1);
	for(int i=1;i<=x;i++){
		for(int j=1;j*i<=x;j++){
			res[i*j].push_back(i);
		}
	}
	return res;
}
vector<int> minimum_prime_fuctors(int x){//linear time
	vector<int> res(x+1);
	vector<int> primes;
	for(int i=2;i<=x;i++){
		if(res[i]==0){
			res[i]=i;
			primes.push_back(i);
		}
		for(int j=0;j<primes.size() && primes[j]<=res[i] && primes[j]*i<=x;j++){
			res[i*primes[j]]=primes[j];
		}
	}
	return res;
}
vector<int> mobius_function(int x){
	vector<int> res(x+1);
	vector<int> mp=minimum_prime_fuctors(x);
	res[1]=1;
	for(int i=2;i<=x;i++){
		if(mp[i]==mp[i/mp[i]]) res[i]=0;
		else res[i]=-res[i/mp[i]];
	}
	return res;
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n,q;
	cin >> n >> q;
	vector<bitset<7001>> a(n);
	vector<vector<int>> di=divs_all(7001);
	vector<int> mo=mobius_function(7001);
	vector<bitset<7001>> mobs(7001);
	for(int i=1;i<=7000;i++){
		for(int j=1;i*j<=7000;j++){
			if(mo[j]!=0) mobs[i][i*j]=1;
		}
	}
	for(int i=0;i<q;i++){
		int ch;
		cin >> ch;
		if(ch==1){
			int x,v;
			cin >> x >> v;
			x--;
			a[x].reset();
			for(int j:di[v]) a[x][j]=1;
		}
		if(ch==2){
			int x,y,z;
			cin >> x >> y >> z;
			x--,y--,z--;
			a[x]=a[y]^a[z];
		}
		if(ch==3){
			int x,y,z;
			cin >> x >> y >> z;
			x--,y--,z--;
			a[x]=a[y]&a[z];
		}
		if(ch==4){
			int x,v;
			cin >> x >> v;
			x--;
			int res=(a[x]&mobs[v]).count();
			if(res&1) cout << 1;
			else cout << 0;
		}
	}
	cout << "\n";
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

vector<vector<int>> divs_all(int x){
	vector<vector<int>> res(x+1);
	for(int i=1;i<=x;i++){
		for(int j=1;j*i<=x;j++){
			res[i*j].push_back(i);
		}
	}
	return res;
}
vector<int> minimum_prime_fuctors(int x){//linear time
	vector<int> res(x+1);
	vector<int> primes;
	for(int i=2;i<=x;i++){
		if(res[i]==0){
			res[i]=i;
			primes.push_back(i);
		}
		for(int j=0;j<primes.size() && primes[j]<=res[i] && primes[j]*i<=x;j++){
			res[i*primes[j]]=primes[j];
		}
	}
	return res;
}
vector<int> mobius_function(int x){
	vector<int> res(x+1);
	vector<int> mp=minimum_prime_fuctors(x);
	res[1]=1;
	for(int i=2;i<=x;i++){
		if(mp[i]==mp[i/mp[i]]) res[i]=0;
		else res[i]=-res[i/mp[i]];
	}
	return res;
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n,q;
	cin >> n >> q;
	vector<bitset<7001>> a(n);
	vector<vector<int>> di=divs_all(7001);
	vector<int> mo=mobius_function(7001);
	for(int i=0;i<q;i++){
		int ch;
		cin >> ch;
		if(ch==1){
			int x,v;
			cin >> x >> v;
			x--;
			a[x].reset();
			for(int j:di[v]) a[x][j]=1;
		}
		if(ch==2){
			int x,y,z;
			cin >> x >> y >> z;
			x--,y--,z--;
			a[x]=a[y]^a[z];
		}
		if(ch==3){
			int x,y,z;
			cin >> x >> y >> z;
			x--,y--,z--;
			a[x]=a[y]&a[z];
		}
		if(ch==4){
			int x,v;
			cin >> x >> v;
			x--;
			int res=a[x][v];
			for(int j=2;(v*j)<=7000;j++){
				res+=mo[j]*a[x][v*j];
			}
			if(res&1) cout << 1;
			else cout << 0;
		}
	}
	cout << "\n";
	return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;

const int N = 1e5 + 5;
const int X = 7000 + 5;

/***************************************************************************/

bitset<X> bs[N];
vector<int> divs[X];
bitset<X> refr;
bitset<X> eff[X];

int main() {

	boost;
	ll sum = 0;
	for(int i=1; i<X; i++) {
		for(int j=i; j<X; j+=i) {
			divs[j].pb(i);
		}
		sum += divs[i].size() * divs[i].size();
	}

	for(int i=1; i<X; i++) {
		refr.reset();
		refr[i] = 1;
		for(auto j=divs[i].rbegin(); j!=divs[i].rend(); j++) {
			if(refr[*j] == 0) continue;
			eff[*j][i] = 1;
			for(auto d : divs[*j]) {
				refr[d] = refr[d] ^ 1;
			}
		}
	}

	int n, q; cin>>n>>q;
	while(q--) {
		int t; cin>>t;
		if(t == 1) {
			int x, v; cin>>x>>v;
			bs[x].reset();
			for(auto it : divs[v]) {
				bs[x][it] = 1;
			}
		}
		else if(t == 2) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] ^ bs[z];
		}
		else if(t == 3) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] & bs[z];
		}
		else {
			int x, v; cin>>x>>v;
			cout<<((bs[x] & eff[v]).count() & 1);
		}
	}
	cout<<"\n";
	return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;

const int N = 1e5 + 5;
const int X = 7000 + 5;

/***************************************************************************/

bitset<X> bs[N];
vector<int> divs[X];
bitset<X> refr;

int main() {

	boost;
	for(int i=1; i<X; i++) {
		for(int j=i; j<X; j+=i) {
			divs[j].pb(i);
		}
	}

	int n, q; cin>>n>>q;
	while(q--) {
		int t; cin>>t;
		if(t == 1) {
			int x, v; cin>>x>>v;
			bs[x].reset();
			for(auto it : divs[v]) {
				bs[x][it] = 1;
			}
		}
		else if(t == 2) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] ^ bs[z];
		}
		else if(t == 3) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] & bs[z];
		}
		else {
			int x, v; cin>>x>>v;
			refr = bs[x];

			int last = v;
			while(last+v < X) last += v;

			while(last > v) {
				if(refr[last]) {
					for(auto it : divs[last]) {
						refr[it] = refr[it] ^ 1;
					}
				}
				last -= v;
			}
			cout<<refr[v];
		}
	}
	cout<<"\n";
	return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;

const int N = 1e5 + 5;
const int X = 7000 + 5;

/***************************************************************************/

bitset<X> bs[N];
vector<int> divs[X];
bitset<X> refr[N];

int main() {

	boost;
	for(int i=1; i<X; i++) {
		for(int j=i; j<X; j+=i) {
			divs[j].pb(i);
		}
	}

	int n, q; cin>>n>>q;
	while(q--) {
		int t; cin>>t;
		if(t == 1) {
			int x, v; cin>>x>>v;
			bs[x].reset();
			for(auto it : divs[v]) {
				bs[x][it] = 1;
			}
			refr[x].reset();
			refr[x][v] = 1;
		}
		else if(t == 2) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] ^ bs[z];
			refr[x] = refr[y] ^ refr[z];
		}
		else if(t == 3) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] & bs[z];

			refr[x] = bs[x];

			for(int i=X-1; i>=1; i--) {
				if(refr[x][i]) {
					for(auto it : divs[i]) {
						refr[x][it] = refr[x][it] ^ 1;
					}
					refr[x][i] = 1;
				}
			}
		}
		else {
			int x, v; cin>>x>>v;
			cout<<refr[x][v];
		}
	}
	cout<<"\n";
	return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;

const int N = 1e5 + 5;
const int X = 7000 + 5;

/***************************************************************************/

bitset<X> bs[N];
vector<int> divs[X];
bitset<X> refr;

int main() {

	boost;
	for(int i=1; i<X; i++) {
		for(int j=i; j<X; j+=i) {
			divs[j].pb(i);
		}
	}

	int n, q; cin>>n>>q;
	while(q--) {
		int t; cin>>t;
		if(t == 1) {
			int x, v; cin>>x>>v;
			bs[x].reset();
			for(auto it : divs[v]) {
				bs[x][it] = 1;
			}
		}
		else if(t == 2) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] ^ bs[z];
		}
		else if(t == 3) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] & bs[z];
		}
		else {
			int x, v; cin>>x>>v;
			refr = bs[x];

			int last = v;
			while(last+v < X) last += v;

			while(last > v) {
				if(refr[last]) {
					for(auto it = divs[last].rbegin(); it!=divs[last].rend() and *it >= v; it++) {
						refr[*it] = refr[*it] ^ 1;
					}
				}
				last -= v;
			}
			cout<<refr[v];
		}
	}
	cout<<"\n";
	return 0;
}


//#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<endl;
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<endl;

#define boost ios::sync_with_stdio(0); cin.tie(0)

#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)

typedef long long ll;
typedef double ld;
typedef pair<int, int> pii;

const int N = 1e5 + 5;
const int X = 7000 + 5;

/***************************************************************************/

bitset<X> bs[N];
vector<int> divs[X];
bitset<X> refr;

int main() {

	boost;
	for(int i=1; i<X; i++) {
		for(int j=i; j<X; j+=i) {
			divs[j].pb(i);
		}
	}

	int n, q; cin>>n>>q;
	while(q--) {
		int t; cin>>t;
		if(t == 1) {
			int x, v; cin>>x>>v;
			bs[x].reset();
			for(auto it : divs[v]) {
				bs[x][it] = 1;
			}
		}
		else if(t == 2) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] ^ bs[z];
		}
		else if(t == 3) {
			int x, y, z; cin>>x>>y>>z;
			bs[x] = bs[y] & bs[z];
		}
		else {
			int x, v; cin>>x>>v;
			refr = bs[x];

			int last = v;
			while(last < X) last += v;

			while(last > v) {
				if(refr[last]) {
					for(auto it : divs[last]) {
						refr[it] = refr[it] ^ 1;
					}
				}
				last -= v;
			}
			cout<<refr[v];
		}
	}
	cout<<"\n";
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<bitset>
#include<iostream>
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int MAXN=100005;
const int MAXM=7005;
bitset<MAXM> b1[MAXN],b2[MAXM],temp,G[MAXM];
int n,Q;
int mu[MAXM],pr[MAXM],plen;bool vis[MAXM];
string ans;
void getmu(int N)
{
	mu[1]=1;
	for(int i=2;i<=N;i++)
	{
		if(!vis[i])pr[++plen]=i,mu[i]=-1;
		for(int j=1;j<=plen&&i*pr[j]<=N;j++)
		{
			vis[i*pr[j]]=true;
			if(!(i%pr[j])){mu[i*pr[j]]=0;break;}
			mu[i*pr[j]]=-mu[i];
		}
	}
}
int main()
{
	getmu(MAXM-5);
	for(int i=1;i<=MAXM-5;i++)
		for(int j=1;j*i<=MAXM-5;j++){
			G[i*j][i]=1;
			if(mu[j])	b2[i][i*j]=1;
		}
	n=read();Q=read();
	while(Q--)
	{
		int opt=read(),u1=read(),u2=read();
		if(opt==1)
		{
			b1[u1]=G[u2];
		}
		else if(opt==2)
		{
			int u3=read();
			b1[u1]=b1[u2]^b1[u3];
		}
		else if(opt==3)
		{
			int u3=read();
			b1[u1]=b1[u2]&b1[u3];
		}
		else
		{
			temp=b1[u1]&b2[u2];
			if(temp.count()&1)ans+='1';
			else ans+='0';
		}
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
#define mod 1e9+7
#define inf 0x3f3f3f
typedef long long ll;
typedef long double ld;
using namespace std;
typedef list<ll> li;
typedef list<ll>::iterator lt;
typedef map<ll,ll>::iterator mt;
typedef vector<ll>::iterator vt;
typedef set<ll>::iterator st;
bitset<7010>b1[100010],b2[7010],t;
int n,q,u[7010],vis[7010],pr[7010],cnt;
string ans;
void getu(int n){
	u[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i])pr[++cnt]=i,u[i]=-1;
		for(int j=1;pr[j]*i<=n,j<=cnt;j++){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)break;
			u[i*pr[j]]=u[i]*(-1);
		}
	}
}
int main(){
    scanf("%d%d",&n,&q);
    getu(7000);
    for(int i=1;i<=7000;i++){
    	for(int j=1;i*j<=7000;j++){
    		if(u[j])b2[i][i*j]=1;
		}
	}
	while(q--){
		int opt,x,y,z,v;
		scanf("%d%d",&opt,&x);
		if(opt==1){
			scanf("%d",&v);
			b1[x].reset();
			for(int i=1;i*i<=v;i++){
				if(v%i==0){
					b1[x][i]=1;
					if(v!=i*i)b1[x][v/i]=1;
				}
			}
		}
		else if(opt==2){
			scanf("%d%d",&y,&z);
			b1[x]=b1[y]^b1[z];
		}
		else if(opt==3){
			scanf("%d%d",&y,&z);
			b1[x]=b1[y]&b1[z];
		}
		else if(opt==4){
			scanf("%d",&v);
			t=b1[x]&b2[v];
			if(t.count()%2==1)ans+='1';
			else ans+='0';
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>

#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)

using namespace std;
typedef long long ll;
const ll N=1e5+10,mo=1e9+7,V=7e3,K=V+1,P=500;

int n,q,op,x,y,z,oo;

int ys[K][P],gs[K];
bool bz[K];
int ss[K],mu[K];

bitset<K> f[N];
bitset<K> mm,uy;
bitset<K> g[K],h[K];

inline int read()
{
	int o=0; char ch=' ';
	for(;ch<'0'||ch>'9';ch=getchar());
	for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+(ch^48);
	return o;
}

inline void prepare()
{
	mu[1]=1;
	fo(i,2,V){
		if(!bz[i])ss[++oo]=i,mu[i]=-1;
		fo(j,1,oo)if(i*ss[j]<=V){
			bz[i*ss[j]]=true;
			mu[ss[j]*i]=-mu[i];
			if(i%ss[j]==0){
				mu[i*ss[j]]=0;
				break;
			}
		}
	}
	mm=0;
	fo(i,1,V)if(mu[i]!=0)mm[i]=1;
	fo(i,1,V){
		int k=(int)sqrt(i);
		g[i]=0;
		fo(l,1,k)if(i%l==0){
			g[i][l]=1;
			g[i][i/l]=1;
		}
	}
	fo(i,1,V){
		h[i]=0;
		fo(l,1,V/i)h[i][l*i]=(mu[l]!=0);
	}
}

int main()
{
	scanf("%d%d",&n,&q);
	prepare();
	fo(i,1,q){
		op=read();
		if(op==1){
			x=read(); y=read();
			f[x]=g[y];
		}
		if(op==2){
			x=read(); y=read(); z=read();
			f[x]=f[y]^f[z];
		}
		if(op==3){
			x=read(); y=read(); z=read();
			f[x]=f[y]&f[z];
		}
		if(op==4){
			x=read(); y=read();
			uy=f[x]&h[y];
			int ans=(uy.count())%2;
			printf("%d",ans);
		}
	}
}
---------------------
作者：DoBelieve
来源：CSDN
原文：https://blog.csdn.net/XianHaoMing/article/details/85880960
版权声明：本文为博主原创文章，转载请附上博文链接！


#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1; char ch; ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return x*f;
}
bitset<7010>b1[100010],b2[7010],G[7010],t;
int u[7010],vis[7010],pr[7010],cnt,n,q;
string ans;
void getu(){
	u[1]=1;
	for(int i=2;i<=7000;i++){
		if(!vis[i])pr[++cnt]=i,u[i]=-1;
		for(int j=1;j<=cnt,pr[j]*i<=7000;j++){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)break;
			u[pr[j]*i]=-u[i];
		}
	}
}
int main(){
   	getu();
   	n=read();q=read();
   	for(int i=1;i<=7000;i++){
   		for(int j=1;j*i<=7000;j++){
   			G[j*i][i]=1;
			if(u[j])b2[i][j*i]=1;
		}
	}
	while(q--){
		int opt,x,y,z,v;
		opt=read();x=read();
		if(opt==1){
			v=read();
			b1[x]=G[v];
		}
		else if(opt==2){
			y=read();z=read();
			b1[x]=b1[y]^b1[z];
		}
		else if(opt==3){
			y=read();z=read();
			b1[x]=b1[y]&b1[z];
		}
		else {
			v=read();
			t=b1[x]&b2[v];
			if(t.count()&1)ans+='1';
			else ans+='0';
		}
	}
	cout<<ans;
	return 0;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
const int LIM = 1e5+5 ,MOD = 1e9+7;
const double EPS = 1e-9;
int n , m , t , x ,y ,v,z, q ;
const int d = 40 , e = d/32+2;
int mob[d][e], di[d][e];
bool issqfree(int r){
	forsn(i,2,(int)sqrt(r)+4){
		kyahai(r,i);
		if( (r % (i*i)) == 0 ) return false;
	}
	return true;
}
int mset[LIM][e];
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>q;
	forsn(i,1,d){
		forsn(j,1,d){
			if( j%i == 0) di[j][i/32] |= (1<<(i%32));
			if( (i%j==0) && issqfree(i/j)) mob[j][i/32] |= (1<<(i%32));
		}
	}
	int ans;
	forn(quer,q){
		cin>>t;
		if(t == 1){
			cin>>x>>v;
			forn(i,e){
				mset[x][i] = di[v][i];
			}
		}else if(t == 3){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] & mset[z][i]);
			}
		}else if(t == 2){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] ^ mset[z][i]);
			}
		}else{
			ans = 0;
			cin>>x>>v;
			forn(i,e){
				ans = (ans + (popc(mset[x][i] & mob[v][i])))%2;
			}
			cout<<ans;
		}
	}
	return 0;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
const int LIM = 1e5+5 ,MOD = 1e9+7;
const double EPS = 1e-9;
int n , m , t , x ,y ,v,z, q ;
const int d = 7002 , e = d/32+2;
int mob[d][e], di[d][e];
bool issqfree(int r){
	forsn(i,2,(int)sqrt(r)+4){
		//kyahai(r,i);
		if( (r % (i*i)) == 0 ) return false;
	}
	return true;
}
int mset[LIM][e];
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>q;
	forsn(i,1,d){
		forsn(j,1,d){
			if( j%i == 0) di[j][i/32] |= (1<<(i%32));
			if( (i%j==0) && issqfree(i/j)) mob[j][i/32] |= (1<<(i%32));
		}
	}
	int ans;
	forn(quer,q){
		cin>>t;
		if(t == 1){
			cin>>x>>v;
			forn(i,e){
				mset[x][i] = di[v][i];
			}
		}else if(t == 3){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] & mset[z][i]);
			}
		}else if(t == 2){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] ^ mset[z][i]);
			}
		}else{
			ans = 0;
			cin>>x>>v;
			forn(i,e){
				ans = (ans + (popc(mset[x][i] & mob[v][i])))%2;
			}
			cout<<ans;
		}
	}
	return 0;
}


//by Shriram Lokhande
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define ln "\n"
#define kyahai(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); \
stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cout<<ln; }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
	cerr << *it << " = " << a << "\t\t";
	err(++it, args...);
}
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(n) n.begin() , n.end()
#define tfi first.first
#define tse first.second
#define tth second
typedef long long ll;
typedef long double ld;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef pair< pair<int,int> , int> tri;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//like set just find_by_order() and order_of_key() are extra

#pragma GCC optimize ("-O3")
template < typename tp > void in( tp & dig ){
    char ch=getchar();dig=0;ll flag=0;
    while(!isdigit(ch)){ if(ch=='-')flag=1;ch=getchar(); }
    while(isdigit(ch))dig=dig*10+ch-'0',ch=getchar();
    if(flag)dig=-dig;
}
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
const int LIM = 1e5+5 ,MOD = 1e9+7;
const double EPS = 1e-9;
int n , m , t , x ,y ,v,z, q ;
const int d = 7002 , e = d/32+2;
int mob[d][e], di[d][e];
bool issqfree(int r){
	forsn(i,2,(int)sqrt(r)+4){
		kyahai(r,i);
		if( (r % (i*i)) == 0 ) return false;
	}
	return true;
}
int mset[LIM][e];
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>q;
	forsn(i,1,d){
		forsn(j,1,d){
			if( j%i == 0) di[j][i/32] |= (1<<(i%32));
			if( (i%j==0) && issqfree(i/j)) mob[j][i/32] |= (1<<(i%32));
		}
	}
	int ans;
	forn(quer,q){
		cin>>t;
		if(t == 1){
			cin>>x>>v;
			forn(i,e){
				mset[x][i] = di[v][i];
			}
		}else if(t == 3){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] & mset[z][i]);
			}
		}else if(t == 2){
			cin>>x>>y>>z;
			forn(i,e){
				mset[x][i] = (mset[y][i] ^ mset[z][i]);
			}
		}else{
			ans = 0;
			cin>>x>>v;
			forn(i,e){
				ans = (ans + (popc(mset[x][i] & mob[v][i])))%2;
			}
			cout<<ans;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int n, q;
bitset <7001> bs[100001], cp;

signed main () {
  scanf ("%d%d", &n, &q);
  while (q--) {
    int t, x, y, z;
    scanf ("%d%d%d", &t, &x, &y);
    if (t == 2 || t == 3) {
      scanf ("%d", &z);
      if (t == 2) {
        bs[x] = bs[y] ^ bs[z];
      } else { // t == 3
        if (bs[y].none()) bs[x] = bs[z];
        else if (bs[z].none()) bs[x] = bs[y];
        else {
          cp.reset();
          for (int i = bs[y]._Find_first(); i < bs[y].size(); i = bs[y]._Find_next(i)) {
            for (int j = bs[z]._Find_first(); j < bs[z].size(); j = bs[z]._Find_next(j)) {
            	int x=__gcd(i,j);
              cp[x] = (cp[x] == 0);
            }
          }
          bs[x] = cp;
        }
      }
    } else {
      if (t == 1) {
        bs[x].reset ();
        bs[x][y] = 1;
      } else { // t == 4
        int cur = bs[x][y];
        printf ("%d", cur);
      }
    }
  }
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fbo find_by_order
#define ook order_of_key
#define f first
#define s second
#define pb push_back
#define reset(a,b) memset(a,b,sizeof a);
#define MOD 998244353
#define MID (l+r)/2
#define ALL(x) x.begin(),x.end()
#define debug(x) cout<<#x<<" = "<<(x)<<endl
#define mx 100003
#define pc(x) putchar_unlocked(x);
#define sz(x) (int)(x.size())
typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;

bitset<7002>dasar[7004],kel[7005],bit[mx];
string ss;
int n,q,x,y,z,v,t,satu[mx];
int main(){

	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i)
			dasar[j][i]=1;
	}
	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i*2){
			if(__gcd(i,j)==i)
				kel[i][j]=1;
		}
		if(i*2<=7000)
			kel[i][i*2]=1;
	}

	scanf("%d%d",&n,&q);
	for(int i=1;i<=q;i++){
		scanf("%d",&t);
		if(t==1){
			scanf("%d%d",&x,&v);
			bit[x]=dasar[v];
		}
		else if(t==2){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]^bit[z];
		}
		else if(t==3){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]&bit[z];
		}
		else{
			scanf("%d%d",&x,&v);
			int ans=(bit[x]&kel[v]).count();
			if(ans&1)ss+='1';
			else ss+='0';
		}
		if(i!=0)continue;
		debug(i);
		for(int x=1;x<=n;x++){
			debug(x);
			for(int j=1;j<=7000;j++){
				if(bit[x][j])
					cout<<j<<' ';
			}
			cout<<endl;
		}
	}
	cout<<ss<<endl;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fbo find_by_order
#define ook order_of_key
#define f first
#define s second
#define pb push_back
#define reset(a,b) memset(a,b,sizeof a);
#define MOD 998244353
#define MID (l+r)/2
#define ALL(x) x.begin(),x.end()
#define debug(x) cout<<#x<<" = "<<(x)<<endl
#define mx 100003
#define pc(x) putchar_unlocked(x);
#define sz(x) (int)(x.size())
typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;

bitset<7002>dasar[7004],kel[7005],bit[mx];
string ss;
bool sq[mx];
int n,q,x,y,z,v,t,satu[mx];
int main(){
	for(int i=2;i<=7000;i++){
		int now=i*i;
		for(int j=now;j<=7000;j+=now)
			sq[j]=true;
	}
	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i)
			dasar[j][i]=1;
	}
	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i){
			if(j/i==1)kel[i][j]=1;
			else if(!sq[j/i])kel[i][j]=1;
		}

	}

	scanf("%d%d",&n,&q);
	for(int i=1;i<=q;i++){
		scanf("%d",&t);
		if(t==1){
			scanf("%d%d",&x,&v);
			bit[x]=dasar[v];
		}
		else if(t==2){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]^bit[z];
		}
		else if(t==3){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]&bit[z];
		}
		else{
			scanf("%d%d",&x,&v);
			int ans=(bit[x]&kel[v]).count();
			if(ans&1)ss+='1';
			else ss+='0';
		}
		if(i!=0)continue;
		debug(i);
		for(int x=1;x<=n;x++){
			debug(x);
			for(int j=1;j<=7000;j++){
				if(bit[x][j])
					cout<<j<<' ';
			}
			cout<<endl;
		}
	}
	cout<<ss<<endl;
}


include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fbo find_by_order
#define ook order_of_key
#define f first
#define s second
#define pb push_back
#define reset(a,b) memset(a,b,sizeof a);
#define MOD 998244353
#define MID (l+r)/2
#define ALL(x) x.begin(),x.end()
#define debug(x) cout<<#x<<" = "<<(x)<<endl
#define mx 100003
#define pc(x) putchar_unlocked(x);
#define sz(x) (int)(x.size())
typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;

bitset<7002>dasar[7004],kel[7005],bit[mx];
string ss;
bool sq[mx];
int n,q,x,y,z,v,t,satu[mx];
int main(){
	for(int i=2;i<=7000;i++){
		int now=i*i;
		for(int j=now;j<=7000;j+=now)
			sq[j]=true;
	}
	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i)
			dasar[j][i]=1;
	}
	for(int i=1;i<=7000;i++){
		for(int j=i;j<=7000;j+=i){
			if(j/i==1)kel[i][j]=1;
			else if(!sq[j/i])kel[i][j]=1;
		}

	}

	scanf("%d%d",&n,&q);
	for(int i=1;i<=q;i++){
		scanf("%d",&t);
		if(t==1){
			scanf("%d%d",&x,&v);
			bit[x]=dasar[v];
		}
		else if(t==2){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]^bit[z];
		}
		else if(t==3){
			scanf("%d%d%d",&x,&y,&z);
			bit[x]=bit[y]&bit[z];
		}
		else{
			scanf("%d%d",&x,&v);
			int ans=(bit[x]&kel[v]).count();
			if(ans&1)ss+='1';
			else ss+='0';
		}
		if(i!=0)continue;
		debug(i);
		for(int x=1;x<=n;x++){
			debug(x);
			for(int j=1;j<=7000;j++){
				if(bit[x][j])
					cout<<j<<' ';
			}
			cout<<endl;
		}
	}
	cout<<ss<<endl;
}


#include <bits/stdc++.h>
#define int long long
#define vec vector
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<long long, long long> PII;
signed main() {
  ios_base::sycn_with_stdio(0), cin.tie(0);
  const int MAX = 7070;
  vec<int> sqfree(MAX, 1);
  for (int i = 1; i < MAX; i++) {
    for (int j = 2; j * j <= i; j++) {
      if (i % (j * j) == 0) {
        sqfree[i] = 0;
        break;
      }
    }
  }
  vec<bitset<MAX>> divs(MAX);
  vec<bitset<MAX>> muls(MAX);
  for (int i = 1; i < MAX; i++) {
    for (int j = 1; j <= i; j++) {
      if (i % j == 0) {
        divs[i].set(j);
        if (sqfree[i / j]) {
          muls[j].set(i);
        }
      }
    }
  }
  int n, tt;
  cin >> n >> tt;
  vec<bitset<MAX>> a(n);
  while (tt--) {
    int op;
    cin >> op;
    if (op == 1) {
      int x, v;
      cin >> x >> v;
      x--;
      a[x] = divs[v];
    }
    if (op == 2) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] ^ a[z];
    }
    if (op == 3) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] & a[z];
    }
    if (op == 4) {
      int x, v;
      cin >> x >> v;
      x--;
      cout << (a[x] & muls[v]).count() % 2;
    }
/*    for (int i = 0; i < n; i++) {
      cout << i << ":";
      for (int j = 0; j < MAX; j++)
        if (a[i][j] == 1) cout << " " << j;
      cout << "; ";
    }
    cout << '\n';*/
  }
  cout << '\n';
  return 0;
}


#include <bits/stdc++.h>
#define int long long
#define vec vector
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<long long, long long> PII;
signed main() {
  const int MAX = 7070;
  vec<int> sqfree(MAX, 1);
  for (int i = 1; i < MAX; i++) {
    for (int j = 2; j * j <= i; j++) {
      if (i % (j * j) == 0) {
        sqfree[i] = 0;
        break;
      }
    }
  }
  vec<bitset<MAX>> divs(MAX);
  vec<bitset<MAX>> muls(MAX);
  for (int i = 1; i < MAX; i++) {
    for (int j = 1; j <= i; j++) {
      if (i % j == 0) {
        divs[i].set(j);
        if (sqfree[i / j]) {
          muls[j].set(i);
        }
      }
    }
  }
  int n, tt;
  cin >> n >> tt;
  vec<bitset<MAX>> a(n);
  while (tt--) {
    int op;
    cin >> op;
    if (op == 1) {
      int x, v;
      cin >> x >> v;
      x--;
      a[x] = divs[v];
    }
    if (op == 2) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] ^ a[z];
    }
    if (op == 3) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] & a[z];
    }
    if (op == 4) {
      int x, v;
      cin >> x >> v;
      x--;
      cout << (a[x] & muls[v]).count() % 2;
    }
/*    for (int i = 0; i < n; i++) {
      cout << i << ":";
      for (int j = 0; j < MAX; j++)
        if (a[i][j] == 1) cout << " " << j;
      cout << "; ";
    }
    cout << '\n';*/
  }
  cout << '\n';
  return 0;
}


#include <bits/stdc++.h>
#define int long long
#define vec vector
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<long long, long long> PII;
signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  const int MAX = 7070;
  vec<int> sqfree(MAX, 1);
  for (int i = 1; i < MAX; i++) {
    for (int j = 2; j * j <= i; j++) {
      if (i % (j * j) == 0) {
        sqfree[i] = 0;
        break;
      }
    }
  }
  vec<bitset<MAX>> divs(MAX);
  vec<bitset<MAX>> muls(MAX);
  for (int i = 1; i < MAX; i++) {
    for (int j = 1; j <= i; j++) {
      if (i % j == 0) {
        divs[i].set(j);
        if (sqfree[i / j]) {
          muls[j].set(i);
        }
      }
    }
  }
  int n, tt;
  cin >> n >> tt;
  vec<bitset<MAX>> a(n);
  while (tt--) {
    int op;
    cin >> op;
    if (op == 1) {
      int x, v;
      cin >> x >> v;
      x--;
      a[x] = divs[v];
    }
    if (op == 2) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] ^ a[z];
    }
    if (op == 3) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] & a[z];
    }
    if (op == 4) {
      int x, v;
      cin >> x >> v;
      x--;
      cout << (a[x] & muls[v]).count() % 2;
    }
/*    for (int i = 0; i < n; i++) {
      cout << i << ":";
      for (int j = 0; j < MAX; j++)
        if (a[i][j] == 1) cout << " " << j;
      cout << "; ";
    }
    cout << '\n';*/
  }
  cout << '\n';
  return 0;
}


#include <bits/stdc++.h>
#define int long long
#define vec vector
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<long long, long long> PII;
int main() {
  const int MAX = 7070;
  vec<int> sqfree(MAX, 1);
  for (int i = 1; i < MAX; i++) {
    for (int j = 2; j * j <= i; j++) {
      if (i % (j * j) == 0) {
        sqfree[i] = 0;
        break;
      }
    }
  }
  vec<bitset<MAX>> divs(MAX);
  vec<bitset<MAX>> muls(MAX);
  for (int i = 1; i < MAX; i++) {
    for (int j = 1; j <= i; j++) {
      if (i % j == 0) {
        divs[i].set(j);
        if (sqfree[i / j]) {
          muls[j].set(i);
        }
      }
    }
  }
  int n, tt;
  cin >> n >> tt;
  vec<bitset<MAX>> a(n);
  while (tt--) {
    int op;
    cin >> op;
    if (op == 1) {
      int x, v;
      cin >> x >> v;
      x--;
      a[x] = divs[v];
    }
    if (op == 2) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] ^ a[z];
    }
    if (op == 3) {
      int x, y, z;
      cin >> x >> y >> z;
      x--; y--; z--;
      a[x] = a[y] & a[z];
    }
    if (op == 4) {
      int x, v;
      cin >> x >> v;
      x--;
      cout << (a[x] & muls[v]).count() % 2;
    }
/*    for (int i = 0; i < n; i++) {
      cout << i << ":";
      for (int j = 0; j < MAX; j++)
        if (a[i][j] == 1) cout << " " << j;
      cout << "; ";
    }
    cout << '\n';*/
  }
  cout << '\n';
  return 0;
}


#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
using matrix = vector<vector<long long>>;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;

template<typename T>
using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define all(x) (x).begin(), (x).end()
//#define int ll

void FAST_IO() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //cout.setf(ios::fixed);
    //cout.precision(20);
}

const int MAXN = 1e5 + 10;
const int MAXD = 7005;
bool sqr[MAXD];
bitset<MAXD> for_first[MAXD], for_fourth[MAXD], a[MAXN];

signed main() {
    FAST_IO();
    for (int i = 2; i < MAXD; ++i) {
        for (int j = i * i; j < MAXD; j += i * i) {
            sqr[j] = true;
        }
    }
    for (int i = 1; i < MAXD; ++i) {
        for (int j = 1; j <= i; ++j) {
            if (i % j == 0) {
                for_first[i][j] = 1;
            }
        }
    }
    for (int i = 1; i < MAXD; ++i) {
        for (int j = i; j < MAXD; j += i) {
            if (!sqr[j / i]) {
                for_fourth[i][j] = 1;
            }
        }
    }
    int n, q;
    cin >> n >> q;
    string ans = "";
    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            a[x] = for_first[v];
        }
        else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] ^ a[z];
        }
        else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] & a[z];
        }
        else {
            int x, v;
            cin >> x >> v;
            ans += char('0' + ((a[x] & for_fourth[v]).count() & 1));
        }
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
using matrix = vector<vector<long long>>;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;

template<typename T>
using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define all(x) (x).begin(), (x).end()
//#define int ll

void FAST_IO() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //cout.setf(ios::fixed);
    //cout.precision(20);
}

const int MAXN = 1e5 + 10;
const int MAXD = 7005;
bool sqr[MAXD];
bitset<MAXD> for_first[MAXD], for_fourth[MAXD], a[MAXN];

signed main() {
    FAST_IO();
    for (int i = 2; i < MAXD; ++i) {
        int a = sqrt(i);
        if (a * a == i) {
            sqr[i] = true;
        }
    }
    for (int i = 1; i < MAXD; ++i) {
        for (int j = 1; j <= i; ++j) {
            if (i % j == 0) {
                for_first[i][j] = 1;
            }
        }
    }
    for (int i = 1; i < MAXD; ++i) {
        for (int j = i; j < MAXD; ++j) {
            if (j % i == 0 && !sqr[j / i]) {
                for_fourth[i][j] = 1;
            }
        }
    }
    int n, q;
    cin >> n >> q;
    string ans = "";
    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            a[x] = for_first[v];
        }
        else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] ^ a[z];
        }
        else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] & a[z];
        }
        else {
            int x, v;
            cin >> x >> v;
            ans += char('0' + (a[x] & for_fourth[v]).count() % 2);
        }
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
using matrix = vector<vector<long long>>;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;

template<typename T>
using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define all(x) (x).begin(), (x).end()
//#define int ll

void FAST_IO() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //cout.setf(ios::fixed);
    //cout.precision(20);
}

const int MAXN = 1e5 + 10;
const int MAXD = 7005;
bitset<MAXD> for_first[MAXD], for_fourth[MAXD], a[MAXN];

signed main() {
    FAST_IO();
    for (int i = 1; i < MAXD; ++i) {
        for (int j = 1; j <= i; ++j) {
            if (i % j == 0) {
                for_first[i][j] = 1;
            }
        }
    }
    for (int i = MAXD - 1; i >= 1; --i) {
        for_fourth[i][i] = 1;
        for (int j = i + i; j < MAXD; j += i) {
            for_fourth[i] ^= for_fourth[j];
        }
    }
    int n, q;
    cin >> n >> q;
    string ans = "";
    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            a[x] = for_first[v];
        }
        else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] ^ a[z];
        }
        else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            a[x] = a[y] & a[z];
        }
        else {
            int x, v;
            cin >> x >> v;
            ans += char('0' + ((a[x] & for_fourth[v]).count() & 1));
        }
    }
    cout << ans;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define FOR(i, s, e) for(int i = (s); i < (e); i++)

#define FOE(i, s, e) for(int i = (s); i <= (e); i++)

#define FOD(i, s, e) for(int i = (s); i >= (e); i--)

#define ll long long

#define mp make_pair

#define pb push_back

#define pii pair<int, int>

#define pff pair<double, double>

bitset<7001> s[100005], val[7001], p[7001], tmp;
int n, m, mo[7001];
vector<int> res;

int solve(int x, int v) {
	tmp = (p[v] & s[x]);
	return tmp.count() % 2;
}

int main () {
	FOE(i, 1, 7000) {
		for (int j = 1; j * j <= i; j++) {
			val[i][j] = 1;
			val[i][i / j] = 1;
		}
		mo[i] = 1;
		for (int j = 2; j * j <= i; j++) if (i % (j * j) == 0) mo[i] = 0;
	}

	FOE(i, 1, 7000) {
		FOE(j, 1, 7000) {
			if (j % i == 0 && mo[j / i] == 1) {
				p[i][j] = 1;
			}
		}
	}

//	FOE(i, 1, 30) printf("%d: %d\n", i, mo[i]);

	scanf("%d %d", &n, &m);

	while (m--) {
		int t;
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			s[x] = val[v];
		}
		else if (t == 2) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] ^ s[z]);
		}
		else if (t == 3) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] & s[z]);
		}
		else {
			int x, v;
			scanf("%d %d", &x, &v);
			int r = solve(x, v);
			res.pb(r);
		}
	}

	for (int i : res) printf("%d", i); puts("");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define FOR(i, s, e) for(int i = (s); i < (e); i++)

#define FOE(i, s, e) for(int i = (s); i <= (e); i++)

#define FOD(i, s, e) for(int i = (s); i >= (e); i--)

#define ll long long

#define mp make_pair

#define pb push_back

#define pii pair<int, int>

#define pff pair<double, double>

bitset<7001> s[100005], val[7001], p[7001], tmp;
int n, m, mo[7001];
vector<int> res;

int solve(int x, int v) {
	tmp = (p[v] & s[x]);
	return tmp.count() % 2;
}

int main () {
	FOE(i, 1, 7000) {
		for (int j = 1; j * j <= i; j++) {
			val[i][j] = 1;
			val[i][i / j] = 1;
		}
		mo[i] = 1;
		for (int j = 2; j * j <= i; j++) if (i % (j * j) == 0) mo[i] = 0;
	}

	FOE(i, 1, 7000) {
		FOE(j, 1, 7000) {
			if (j % i == 0 && mo[j / i] == 1) p[i][j] = 1;
		}
	}

//	FOE(i, 1, 30) printf("%d: %d\n", i, mo[i]);

	scanf("%d %d", &n, &m);

	while (m--) {
		int t;
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			s[x] ^= val[v];
		}
		else if (t == 2) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] ^ s[z]);
		}
		else if (t == 3) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] & s[z]);
		}
		else {
			int x, v;
			scanf("%d %d", &x, &v);
			int r = solve(x, v);
			res.pb(r);
		}
	}

	for (int i : res) printf("%d", i); puts("");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define FOR(i, s, e) for(int i = (s); i < (e); i++)
#define FOE(i, s, e) for(int i = (s); i <= (e); i++)
#define FOD(i, s, e) for(int i = (s); i >= (e); i--)
#define ll long long
#define mp make_pair
#define pb push_back
#define pii pair<int, int>
#define pff pair<double, double>

bitset<7001> s[100005], val[7001], p[7001], tmp;
int n, m, mo[7001];
vector<int> res;

int solve(int x, int v) {
	tmp = (p[v] & s[x]);
	return tmp.count() % 2;
}

int main () {
	FOE(i, 1, 7000) {
		for (int j = 1; j * j <= i; j++) {
			if (i % j != 0) continue;
			val[i][j] = 1;
			val[i][i / j] = 1;
		}
		mo[i] = 1;
		for (int j = 2; j * j <= i; j++) if (i % (j * j) == 0) mo[i] = 0;
	}

	FOE(i, 1, 7000) {
		FOE(j, 1, 7000) {
			if (j % i == 0 && mo[j / i] == 1) {
				p[i][j] = 1;
			}
		}
	}

//	FOE(i, 1, 30) printf("%d: %d\n", i, mo[i]);

	scanf("%d %d", &n, &m);

	while (m--) {
		int t;
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			s[x] &= 0;
			s[x] |= val[v];
		}
		else if (t == 2) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] ^ s[z]);
		}
		else if (t == 3) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] & s[z]);
		}
		else {
			int x, v;
			scanf("%d %d", &x, &v);
			int r = solve(x, v);
			res.pb(r);
		}
	}

	for (int i : res) printf("%d", i); puts("");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define FOR(i, s, e) for(int i = (s); i < (e); i++)

#define FOE(i, s, e) for(int i = (s); i <= (e); i++)

#define FOD(i, s, e) for(int i = (s); i >= (e); i--)

#define ll long long

#define mp make_pair

#define pb push_back

#define pii pair<int, int>

#define pff pair<double, double>

bitset<7001> s[100005], val[7001], p[7001], tmp;
int n, m, mo[7001];
vector<int> res;

int solve(int x, int v) {
	tmp = (p[v] & s[x]);
	return tmp.count() % 2;
}

int main () {
	FOE(i, 1, 7000) {
		for (int j = 1; j * j <= i; j++) {
			val[i][j] = 1;
			val[i][i / j] = 1;
		}
		mo[i] = 1;
		for (int j = 2; j * j <= i; j++) if (i % (j * j) == 0) mo[i] = 0;
	}

	FOE(i, 1, 7000) {
		FOE(j, 1, 7000) {
			if (j % i == 0 && mo[j / i] == 1) {
				p[i][j] = 1;
			}
		}
	}

//	FOE(i, 1, 30) printf("%d: %d\n", i, mo[i]);

	scanf("%d %d", &n, &m);

	while (m--) {
		int t;
		scanf("%d", &t);
		if (t == 1) {
			int x, v;
			scanf("%d %d", &x, &v);
			s[x] &= 0;
			s[x] |= val[v];
		}
		else if (t == 2) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] ^ s[z]);
		}
		else if (t == 3) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			s[x] = (s[y] & s[z]);
		}
		else {
			int x, v;
			scanf("%d %d", &x, &v);
			int r = solve(x, v);
			res.pb(r);
		}
	}

	for (int i : res) printf("%d", i); puts("");
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;

vector<int>fac[7010];
bitset<7010>msk[7010],a[100010];

int main()
{
    for (int i=1;i<=7000;i++)
        for (int j=i;j<=7000;j+=i)
            fac[j].push_back(i);
    for (int i=7000;i>=1;i--)
    {
        msk[i][i]=1-msk[i][i];
        for (int x=0;x<fac[i].size()-1;x++)
            msk[fac[i][x]]^=msk[i];
    }
    int n,q;
    scanf("%d%d",&n,&q);
    while (q--)
    {
        int ty;
        scanf("%d",&ty);
        if (ty==1)
        {
            int x,v;
            scanf("%d%d",&x,&v);
            a[x].reset();
            for (int i=0;i<fac[v].size();i++) a[x][fac[v][i]]=1;
        }
        else if (ty==2)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]^a[z];
        }
        else if (ty==3)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]&a[z];
        }
        else
        {
            int x,v;
            scanf("%d%d",&x,&v);
            printf("%d",(a[x]&msk[v]).count()&1);
        }
    }
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;

vector<int>fac[7010];
bitset<7010>msk[7010],a[100010];

int main()
{
    for (int i=1;i<=7000;i++)
        for (int j=i;j<=7000;j+=i)
            fac[j].push_back(i);
    for (int i=7000;i>=1;i--)
    {
        msk[i][i]=1-msk[i][i];
        for (int x=1;x<fac[i].size();x++)
            msk[fac[i][x]]^=msk[i];
    }
    int n,q;
    scanf("%d%d",&n,&q);
    while (q--)
    {
        int ty;
        scanf("%d",&ty);
        if (ty==1)
        {
            int x,v;
            scanf("%d%d",&x,&v);
            a[x].reset();
            for (int i=0;i<fac[v].size();i++) a[x][fac[v][i]]=1;
        }
        else if (ty==2)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]^a[z];
        }
        else if (ty==3)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]&a[z];
        }
        else
        {
            int x,v;
            scanf("%d%d",&x,&v);
            printf("%d",(a[x]&msk[v]).count()&1);
        }
    }
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;

vector<int>fac[7010];
bitset<7010>msk[7010],a[100010];

int main()
{
    for (int i=1;i<=7000;i++)
        for (int j=i;j<=7000;j+=i)
            fac[j].push_back(i);
    for (int i=7000;i>=1;i--)
    {
        msk[i][i]=1-msk[i][i];
        for (int x=0;x<fac[i].size();x++)
            if (fac[i][x]!=i) msk[fac[i][x]]^=msk[i];
    }
    int n,q;
    scanf("%d%d",&n,&q);
    while (q--)
    {
        int ty;
        scanf("%d",&ty);
        if (ty==1)
        {
            int x,v;
            scanf("%d%d",&x,&v);
            a[x].reset();
            for (int i=0;i<fac[v].size();i++) a[x][fac[v][i]]=1;
        }
        else if (ty==2)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]^a[z];
        }
        else if (ty==3)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x]=a[y]&a[z];
        }
        else
        {
            int x,v;
            scanf("%d%d",&x,&v);
            printf("%d",(a[x]&msk[v]).count()&1);
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);

    constexpr int MXV = 7'000, MXQ = 1'000'000;

    vector<int> sqfree(MXV + 1, 1);
    for (int i = 1; i <= MXV; ++i) {
        for (int j = 2; j * j <= i; ++j) {
            if (i % (j * j) == 0) {
                sqfree[i] = 0;
                break;
            }
        }
    }
    vector<bitset<MXV + 1>> div(MXV + 1), mob(MXV + 1);
    for (int i = 1; i <= MXV; ++i) {
        for (int j = 1; j <= i; ++j) {
            if (i % j == 0) {
                div[i][j] = 1;
                if (sqfree[i / j]) {
                    mob[j][i] = 1;
                }
            }
        }
    }

    int n, q;
    cin >> n >> q;
    vector<bitset<MXV + 1>> sets(MXQ);
    for (int i = 0; i < q; ++i) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            --x;
            sets[x] = div[v];
        } else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] ^ sets[z];
        } else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] & sets[z];
        } else {
            assert(t == 4);
            int x, v;
            cin >> x >> v;
            --x;
            bitset<MXV + 1> tmp = sets[x] & mob[v];
            cout << tmp.count() % 2 << "";
        }
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);

    constexpr int MXV = 7'000;

    vector<int> sqfree(MXV + 1, 1);
    for (int i = 1; i <= MXV; ++i) {
        for (int j = 2; j * j <= i; ++j) {
            if (i % (j * j) == 0) {
                sqfree[i] = 0;
                break;
            }
        }
    }
    vector<bitset<MXV + 1>> div(MXV + 1), mob(MXV + 1);
    for (int i = 1; i <= MXV; ++i) {
        for (int j = 1; j <= i; ++j) {
            if (i % j == 0) {
                div[i][j] = 1;
                if (sqfree[i / j]) {
                    mob[j][i] = 1;
                }
            }
        }
    }

    int n, q;
    cin >> n >> q;
    vector<bitset<MXV + 1>> sets(n);
    for (int i = 0; i < q; ++i) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            --x;
            sets[x] = div[v];
        } else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] ^ sets[z];
        } else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] & sets[z];
        } else {
            assert(t == 4);
            int x, v;
            cin >> x >> v;
            --x;
            bitset<MXV + 1> tmp = sets[x] & mob[v];
            cout << tmp.count() % 2 << "";
        }
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);

    constexpr int MXV = 7'000;

    vector<int> sq_free(MXV + 1, 1);
    for (int i = 1; i <= MXV; ++i) {
        for (int j = 2; j * j <= i; ++j) {
            if (i % (j * j) == 0) {
                sq_free[i] = 0;
                break;
            }
        }
    }
    vector<bitset<MXV + 1>> div(MXV + 1), mob(MXV + 1);
    for (int x = 1; x <= MXV; ++x) {
        for (int i = 1; i <= x; ++i) {
            div[x][i] = (x % i == 0);
        }
    }
    for (int i = 1; i <= MXV; ++i) {
        for (int x = 1; x <= i; ++x) {
            mob[x][i] = (i % x == 0 && sq_free[i / x]);
        }
    }

    int n, q;
    cin >> n >> q;
    vector<bitset<MXV + 1>> sets(n);
    for (int i = 0; i < q; ++i) {
        int t;
        cin >> t;
        if (t == 1) {
            int x, v;
            cin >> x >> v;
            --x;
            sets[x] = div[v];
        } else if (t == 2) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] ^ sets[z];
        } else if (t == 3) {
            int x, y, z;
            cin >> x >> y >> z;
            --x; --y; --z;
            sets[x] = sets[y] & sets[z];
        } else {
            assert(t == 4);
            int x, v;
            cin >> x >> v;
            --x;
            bitset<MXV + 1> tmp = sets[x] & mob[v];
            cout << tmp.count() % 2 << "";
        }
    }

    return 0;
}


/*
 Julia M.(aka Andrei Konstantinovich)
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
#define x first
#define y second
#define ll long long
#define pii pair<ll, ll>
#define ld long double
const int MN = 1e5 + 111, MT = 7001;
bitset<MT> r[MN];
bitset<MT> prep[MT], prepmask[MT];

int32_t main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    for (int i = 1; i < MT; ++i)
    {
        for (int j = 1; j <= i; ++j)
        {
            if (i % j == 0)
            {
                prep[i][j] = 1;
            }
        }
    }
    for (int i = 1; i < MT; ++i)
    {
        for (int j = i; j < MT; j += i)
        {
            prepmask[i][j] = 1;
        }
    }

    int n, q;
    cin >> n >> q;
    for (int i = 0; i < q; ++i)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int x, v;
            cin >> x >> v;
            x--;
            r[x] = prep[v];
        }
        else if (t == 2)
        {
            int x, y, z;
            cin >> x >> y >> z;
            x--;
            y--;
            z--;
            r[x] = r[y] ^ r[z];
        }
        else if (t == 3)
        {
            int x, y, z;
            cin >> x >> y >> z;
            x--;
            y--;
            z--;
            r[x] = r[y] & r[z];
        }
        else
        {
            int x, v;
            cin >> x >> v;
            x--;
            if (v > 1)
            {
                cout << (((r[x] & prepmask[v]).count()) & 1);
            }
            else
            {
                cout << (((r[x] & prepmask[v]).count() + 1) & 1);
            }
        }
    }
}


/*
 Julia M.(aka Andrei Konstantinovich)
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
#define x first
#define y second
#define ll long long
#define pii pair<ll, ll>
#define ld long double
const int MN = 1e5 + 111, MT = 7001;
bitset<MT> r[MN];
bitset<MT> prep[MT], prepmask[MT];
int sq[MT];

int32_t main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    for (int i = 1; i < MT; ++i)
    {
        for (int j = i; j < MT; j += i)
        {
            prep[j][i] = 1;
        }
    }
    for (int i = 2; i < MT; i++)
    {
        for (int k = 2; k * k < MT; ++k)
        {
            if (i % (k * k) == 0)
                sq[i] = 1;
        }
    }

    for (int i = 1; i < MT; ++i)
    {
        for (int j = i; j < MT; j += i)
        {
            if (sq[j / i])
                continue;
            prepmask[i][j] = 1;
        }
    }

    int n, q;
    cin >> n >> q;
    for (int i = 0; i < q; ++i)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int x, v;
            cin >> x >> v;
            x--;
            r[x] = prep[v];
        }
        else if (t == 2)
        {
            int x, y, z;
            cin >> x >> y >> z;
            x--;
            y--;
            z--;
            r[x] = r[y] ^ r[z];
        }
        else if (t == 3)
        {
            int x, y, z;
            cin >> x >> y >> z;
            x--;
            y--;
            z--;
            r[x] = r[y] & r[z];
        }
        else
        {
            int x, v;
            cin >> x >> v;
            x--;
            cout << (((r[x] & prepmask[v]).count()) & 1);
        }
    }
}