#include <bits/stdc++.h>
using namespace std;
int N, V[(1 << 19)], B[19][(1 << 19)], K[19][(1 << 19)], nr[19][(1 << 19)],
    ind[19][(1 << 19)], sol[(1 << 19)];
bool is_used(int x) { return x < 0; }
int minimize(int* ret, int* nrret, int* ind, int n) {
  int i = 0;
  for (; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      if (ret[j] > ret[i]) {
        swap(ret[i], ret[j]);
        if (nrret) swap(nrret[i], nrret[j]);
      }
    }
    if (!ret[i]) break;
    for (int j = i + 1; j < n; j++) {
      int x = ret[i];
      int y = ret[j];
      if ((x ^ y) > y) continue;
      ret[j] ^= x;
      if (nrret) nrret[j] += nrret[i];
    }
  }
  if (ind && nrret) {
    ind[0] = -1;
    for (int j = i; j < n; j++)
      if (nrret[j] & 1) {
        ind[0] = j;
        break;
      }
  }
  return i;
}
int add(int* A, int* nrA, int a, int* ret, int* nrret) {
  int z = 0;
  for (int i = 0; i < a && A[i]; i++) {
    ret[z] = A[i];
    if (nrA && nrret)
      nrret[z++] = nrA[i];
    else
      z++;
  }
  return z;
}
void combine(int h, int l, int r, int mid) {
  int z = l;
  z += add(&B[h + 1][l], &nr[h + 1][l], mid - l + 1, &B[h][z], &nr[h][z]);
  z += add(&B[h + 1][mid + 1], &nr[h + 1][mid + 1], r - mid, &B[h][z],
           &nr[h][z]);
  int k = -1;
  if (ind[h + 1][l] != -1) {
    k = ind[h + 1][l] + l;
  } else if (ind[h + 1][mid + 1] != -1) {
    k = ind[h + 1][mid + 1] + mid + 1;
  }
  if (k != -1) {
    B[h][z] = B[h + 1][k];
    nr[h][z] = nr[h + 1][k];
    ind[h][l] = z - l;
    z++;
  }
  z = minimize(&B[h][l], &nr[h][l], &ind[h][l], z - l);
  if (z + l <= r) B[h][z + l] = 0;
}
void build(int l, int r, int h = 0) {
  if (l == r) {
    B[h][l] = V[l];
    nr[h][l] = 1;
    ind[h][l] = V[l] == 0 ? 0 : -1;
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, h + 1);
  build(mid + 1, r, h + 1);
  combine(h, l, r, mid);
}
void update(int x, int a, int b, int l, int r, int h = 0) {
  if (a <= l && r <= b) {
    K[h][l] ^= x;
    int i;
    for (i = l; i <= r && B[h][i]; i++)
      if (nr[h][i] & 1) B[h][i] ^= x;
    if (ind[h][l] != -1) {
      int k = ind[h][l] + l;
      swap(B[h][i], B[h][k]);
      swap(nr[h][i], nr[h][k]);
      B[h][i] ^= x;
      i++;
    }
    minimize(&B[h][l], &nr[h][l], &ind[h][l], i - l);
    return;
  }
  if (l > b || r < a) return;
  int mid = (l + r) >> 1;
  if (K[h][l]) {
    update(K[h][l], l, r, l, mid, h + 1);
    update(K[h][l], l, r, mid + 1, r, h + 1);
    K[h][l] = 0;
  }
  update(x, a, b, l, mid, h + 1);
  update(x, a, b, mid + 1, r, h + 1);
  combine(h, l, r, mid);
}
void query(int& z, int a, int b, int l, int r, int h = 0) {
  if (a <= l && r <= b) {
    z += add(&B[h][l], 0, r - l + 1, &sol[z], 0);
    return;
  }
  if (l > b || r < a) return;
  int mid = (l + r) >> 1;
  if (K[h][l]) {
    update(K[h][l], l, r, l, mid, h + 1);
    update(K[h][l], l, r, mid + 1, r, h + 1);
    K[h][l] = 0;
  }
  query(z, a, b, l, mid, h + 1);
  query(z, a, b, mid + 1, r, h + 1);
}
int main() {
  int Q;
  scanf("%d %d", &N, &Q);
  for (int i = 0; i < N; i++) scanf("%d", V + i);
  build(0, N - 1);
  int best = 0;
  for (int i = 0; i < Q; i++) {
    int t, l, r, k;
    scanf("%d %d %d ", &t, &l, &r);
    l--, r--;
    if (t == 1) {
      scanf("%d ", &k);
      update(k, l, r, 0, N - 1);
    } else {
      int z = 0;
      query(z, l, r, 0, N - 1);
      best = max(z, best);
      z = minimize(sol, 0, 0, z);
      printf("%d\n", 1 << z);
    }
  }
  return 0;
}
