#include <bits/stdc++.h>
using namespace std;
int qread() {
  char c;
  int s = 0, t = 1;
  while ((c = getchar()) < '0' || c > '9') (c == '-') && (t = -1);
  do s = s * 10 + c - '0';
  while ((c = getchar()) >= '0' && c <= '9');
  return s * t;
}
int n, m;
int num[200011];
struct SMT {
  struct Node {
    int ji[33], ls, rs;
  } a[200011 << 1];
  int size, n;
  void in(int ji[33], int v) {
    for (int i = 30; ~i; i--)
      if ((v >> i) & 1) {
        if (ji[i])
          v ^= ji[i];
        else {
          ji[i] = v;
          break;
        }
      }
  }
  void up(int x) {
    memcpy(a[x].ji, a[a[x].ls].ji, sizeof(a[x].ji));
    for (int i = 0; i <= 30; i++)
      if (a[a[x].rs].ji[i]) in(a[x].ji, a[a[x].rs].ji[i]);
  }
  void build(int &x, int L, int R) {
    x = ++size;
    if (L == R) {
      in(a[x].ji, num[L]);
      return;
    }
    int mid = (L + R) >> 1;
    build(a[x].ls, L, mid);
    build(a[x].rs, mid + 1, R);
    up(x);
  }
  void clear(int N) {
    n = N;
    size = 0;
    int x;
    build(x, 1, n);
  }
  int ql, qr, v;
  void Add(int x, int L, int R) {
    if (L == R) {
      int tmp = 0;
      for (int i = 0; i <= 30; i++)
        if (a[x].ji[i]) tmp = a[x].ji[i];
      memset(a[x].ji, 0, sizeof(a[x].ji));
      in(a[x].ji, tmp ^ v);
      return;
    }
    int mid = (L + R) >> 1;
    if (ql <= mid)
      Add(a[x].ls, L, mid);
    else
      Add(a[x].rs, mid + 1, R);
    up(x);
  }
  void add(int p, int V) {
    if (p > n) return;
    ql = p;
    v = V;
    Add(1, 1, n);
  }
  int tt[33];
  void Query(int x, int L, int R) {
    if (ql <= L && R <= qr) {
      for (int i = 0; i <= 30; i++)
        if (a[x].ji[i]) in(tt, a[x].ji[i]);
      tt[31] |= a[x].ji[31];
      return;
    }
    int mid = (L + R) >> 1;
    if (ql <= mid) Query(a[x].ls, L, mid);
    if (qr > mid) Query(a[x].rs, mid + 1, R);
  }
  void query(int l, int r) {
    ql = l;
    qr = r;
    memset(tt, 0, sizeof(tt));
    if (l > r) return;
    Query(1, 1, n);
  }
  void test(int x, int L, int R) {
    cout << L << '~' << R << endl;
    for (int i = 0; i <= 31; i++) cout << a[x].ji[i] << ' ';
    cout << endl;
    int mid = (L + R) >> 1;
    if (a[x].ls) test(a[x].ls, L, mid), test(a[x].rs, mid + 1, R);
  }
} t;
struct BIT {
  int a[200011], n;
  void clear(int N) {
    n = N;
    memset(a, 0, sizeof(a));
  }
  void add(int x, int v) {
    for (; x <= n; x += x & -x) a[x] ^= v;
  }
  int query(int x) {
    int ans = 0;
    for (; x; x -= x & -x) ans ^= a[x];
    return ans;
  }
} tt;
int main() {
  n = qread();
  m = qread();
  tt.clear(n);
  for (int i = 1; i <= n; i++) num[i] = qread();
  for (int i = n; i >= 1; i--) {
    num[i] ^= num[i - 1];
    tt.add(i, num[i]);
  }
  t.clear(n);
  int op, x, y, v;
  while (m--) {
    op = qread();
    if (op == 1) {
      x = qread();
      y = qread();
      v = qread();
      tt.add(x, v);
      tt.add(y + 1, v);
      t.add(x, v);
      t.add(y + 1, v);
    } else {
      x = qread();
      y = qread();
      t.query(x + 1, y);
      t.in(t.tt, tt.query(x));
      int cnt = 0;
      for (int i = 0; i <= 30; i++)
        if (t.tt[i]) cnt++;
      printf("%d\n", (1 << cnt));
    }
  }
  return 0;
}
