#include <bits/stdc++.h>
using namespace std;
const long long N = 1e6 + 5;
long long n, m, val, a[N], tree[N * 4], tree2[N * 4], lazy[N * 4];
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline long long gc() {
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline long long read() {
  long long res = 0, f = 1;
  char c = gc();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = gc();
  }
  while (isdigit(c)) {
    res = res * 10 + c - 48;
    c = gc();
  }
  return res * f;
}
void build(long long nod, long long l, long long r) {
  if (l == r) {
    tree[nod] = a[l];
    return;
  }
  long long mid = (l + r) / 2;
  build(nod * 2, l, mid);
  build(nod * 2 + 1, mid + 1, r);
  tree[nod] = tree[nod * 2] | tree[nod * 2 + 1];
}
void change(long long nod, long long l, long long r, long long x,
            long long val) {
  if (l == r) {
    tree[nod] = val;
    return;
  }
  long long mid = (l + r) / 2;
  if (x <= mid)
    change(nod * 2, l, mid, x, val);
  else
    change(nod * 2 + 1, mid + 1, r, x, val);
  tree[nod] = tree[nod * 2] | tree[nod * 2 + 1];
}
long long find(long long nod, long long l, long long r, long long L,
               long long R) {
  if (L > R) return -1;
  if (l == L && r == R) return tree[nod];
  long long mid = (l + r) / 2;
  if (R <= mid)
    return find(nod * 2, l, mid, L, R);
  else if (L > mid)
    return find(nod * 2 + 1, mid + 1, r, L, R);
  else
    return find(nod * 2, l, mid, L, mid) |
           find(nod * 2 + 1, mid + 1, r, mid + 1, R);
}
void pushdown(long long nod, long long l, long long r) {
  long long mid = (l + r) / 2;
  if (lazy[nod]) {
    tree2[nod * 2] = (mid - l + 1) * lazy[nod];
    tree2[nod * 2 + 1] = (r - mid) * lazy[nod];
    lazy[nod * 2] = lazy[nod];
    lazy[nod * 2 + 1] = lazy[nod];
    lazy[nod] = 0;
  }
}
void change2(long long nod, long long l, long long r, long long L, long long R,
             long long val) {
  if (l == L && r == R) {
    tree2[nod] = val * (r - l + 1);
    lazy[nod] = val;
    return;
  }
  pushdown(nod, l, r);
  long long mid = (l + r) / 2;
  if (R <= mid)
    change2(nod * 2, l, mid, L, R, val);
  else if (L > mid)
    change2(nod * 2 + 1, mid + 1, r, L, R, val);
  else {
    change2(nod * 2, l, mid, L, mid, val);
    change2(nod * 2 + 1, mid + 1, r, mid + 1, R, val);
  }
  tree2[nod] = tree2[nod * 2] + tree2[nod * 2 + 1];
}
long long find2(long long nod, long long l, long long r, long long L,
                long long R) {
  if (l == L & r == R) return tree2[nod];
  pushdown(nod, l, r);
  long long mid = (l + r) / 2;
  if (R <= mid)
    return find2(nod * 2, l, mid, L, R);
  else if (L > mid)
    return find2(nod * 2 + 1, mid + 1, r, L, R);
  else
    return find2(nod * 2, l, mid, L, mid) +
           find2(nod * 2 + 1, mid + 1, r, mid + 1, R);
}
signed main() {
  n = read();
  m = read();
  val = read();
  if (val == 0) {
    for (long long i = 1; i <= n; i++) a[i] = read();
    while (m--) {
      long long opt = read(), l = read(), r = read();
      if (opt == 1) {
        a[l] = r;
      } else {
        long long len = (r - l + 1);
        long long ans = (1 + len) * len / 2;
        printf("%lld\n", ans);
      }
    }
    return 0;
  }
  for (long long i = 1; i <= n; i++) a[i] = min(val, read());
  n++;
  a[n] = val;
  build(1, 1, n);
  for (long long i = 1; i <= n; i++) {
    long long l = i, r = n;
    while (l < r) {
      long long mid = (l + r) / 2;
      if (find(1, 1, n, i, mid) >= val)
        r = mid;
      else
        l = mid + 1;
    }
    change2(1, 1, n, i, i, r);
  }
  while (m--) {
    long long opt = read();
    if (opt == 1) {
      long long x = read(), y = read();
      a[x] = min(val, y);
      change(1, 1, n, x, y);
      long long l = 1, r = x;
      while (l < r) {
        long long mid = (l + r) / 2;
        if (find2(1, 1, n, mid, mid) >= x)
          r = mid;
        else
          l = mid + 1;
      }
      y = r;
      for (long long i = y, j = y; i <= x; i = j + 1) {
        long long l = i, r = n;
        while (l < r) {
          long long mid = (l + r) / 2;
          if (find(1, 1, n, i, mid) >= val)
            r = mid;
          else
            l = mid + 1;
        }
        long long pos = r;
        l = i, r = x;
        while (l < r) {
          long long mid = (l + r + 1) / 2;
          if (find(1, 1, n, mid, pos) >= val)
            l = mid;
          else
            r = mid - 1;
        }
        j = l;
        change2(1, 1, n, i, j, pos);
      }
    } else {
      long long x = read(), y = read(), len = y - x + 1;
      if (find2(1, 1, n, x, x) > y) {
        puts("0");
        continue;
      }
      long long l = x, r = y;
      while (l < r) {
        long long mid = (l + r + 1) / 2;
        if (find2(1, 1, n, mid, mid) <= y)
          l = mid;
        else
          r = mid - 1;
      }
      long long res = find2(1, 1, n, x, l) - (x + l) * (l - x + 1) / 2;
      long long ans = (len + y - l + 1) * (l - x + 1) / 2;
      printf("%lld\n", ans - res);
    }
  }
}
