#include <bits/stdc++.h>
using namespace std;
const int maxn = 300020;
const int maxm = 1000020;
const int MOd = 1e9;
struct node {
  int l[22], r[22], sl[22], sr[22];
  int ken, lsi, rsi;
  long long tot;
  node(int _x = 0) {
    tot = _x;
    ken = 0;
  }
};
node segment[maxn];
int a, q, x, ar[maxn], n;
void add(int i, int y) {
  for (int j = 0; j < 20; j++)
    segment[i + n - 1].sr[j] = segment[i + n - 1].sl[j] = 0;
  segment[i + n - 1].lsi = 1;
  segment[i + n - 1].rsi = 1;
  segment[i + n - 1].tot = (y >= x);
  segment[i + n - 1].ken = y;
  segment[i + n - 1].l[0] = y;
  segment[i + n - 1].r[0] = y;
  segment[i + n - 1].sr[0] = 1;
  segment[i + n - 1].sl[0] = 1;
}
void print(node a) {}
node merge(node a, node b) {
  if (a.tot == -1) return b;
  if (b.tot == -1) return a;
  node t;
  t.ken = a.ken | b.ken;
  t.tot = a.tot + b.tot;
  for (int i = 0; i < a.rsi; i++)
    for (int j = 0; j < b.lsi; j++)
      if ((b.l[j] | a.r[i]) >= x) t.tot += (long long)a.sr[i] * b.sl[j];
  for (int i = 0; i < b.lsi; i++) {
    int h = b.l[i];
    int sz = b.sl[i];
    int last = a.lsi - 1;
    if ((a.ken | h) != a.l[last]) {
      a.l[a.lsi] = (a.ken | h);
      a.sl[a.lsi] = sz;
      a.lsi++;
    } else {
      a.sl[last] += sz;
    }
  }
  t.lsi = a.lsi;
  for (int i = 0; i < a.lsi; i++) t.l[i] = a.l[i], t.sl[i] = a.sl[i];
  for (int i = 0; i < a.rsi; i++) {
    int h = a.r[i];
    int sz = a.sr[i];
    int last = b.rsi - 1;
    if ((b.ken | h) != b.r[last]) {
      b.r[b.rsi] = (b.ken | h);
      b.sr[b.rsi] = sz;
      b.rsi++;
    } else {
      b.sr[last] += sz;
    }
  }
  t.rsi = b.rsi;
  for (int i = 0; i < b.rsi; i++) t.r[i] = b.r[i], t.sr[i] = b.sr[i];
  return t;
}
node find(int k, int b, int s, int x, int y) {
  if (x > s || b > y) return node(-1);
  if (x <= b && s <= y) return segment[k];
  return merge(find(k + k, b, (b + s) / 2, x, y),
               find(k + k + 1, (b + s) / 2 + 1, s, x, y));
}
int main() {
  scanf("%d %d %d", &a, &q, &x);
  n = 1;
  while (n < a) n <<= 1;
  for (int i = 1; i < n + n; i++) segment[i].tot = -1;
  for (int i = 1; i <= a; i++) {
    scanf("%d", &ar[i]);
    int x = ar[i];
    add(i, x);
  }
  for (int i = n - 1; i >= 1; i--)
    segment[i] = merge(segment[i + i], segment[i + i + 1]);
  while (q--) {
    int tp, x, y;
    scanf("%d %d %d", &tp, &x, &y);
    if (tp == 1) {
      ar[x] = y;
      add(x, y);
      for (int i = (x + n - 1) >> 1; i; i >>= 1)
        segment[i] = merge(segment[i + i], segment[i + i + 1]);
    } else {
      node t = find(1, 1, n, x, y);
      cout << t.tot << endl;
    }
  }
  return 0;
}
