#include <bits/stdc++.h>
using namespace std;
int n, m, x;
struct Segment {
  int cL, cR;
  pair<int, int> vL[21], vR[21];
  long long sum;
} seg[100001 << 1 | 1];
void seg_up(Segment &rt, Segment &lft, Segment &rht) {
  rt.cL = lft.cL;
  memcpy(rt.vL, lft.vL, rt.cL * sizeof(pair<int, int>));
  for (int i = 0; i < rht.cL; ++i) {
    pair<int, int> pre = rt.vL[rt.cL - 1];
    pair<int, int> cur = rht.vL[i];
    cur.first |= pre.first;
    if (pre.first < cur.first) rt.vL[rt.cL++] = cur;
  }
  rt.cR = rht.cR;
  memcpy(rt.vR, rht.vR, rt.cR * sizeof(pair<int, int>));
  for (int i = 0; i < lft.cR; ++i) {
    pair<int, int> pre = rt.vR[rt.cR - 1];
    pair<int, int> cur = lft.vR[i];
    cur.first |= pre.first;
    if (pre.first < cur.first) rt.vR[rt.cR++] = cur;
  }
  rt.sum = lft.sum + rht.sum;
  for (int i = lft.cR - 1, j = 0; i >= 0; --i) {
    for (; j < rht.cL && (lft.vR[i].first | rht.vL[j].first) < x; ++j)
      ;
    if (j < rht.cL)
      rt.sum += (lft.vR[i].second - (i + 1 < lft.cR ? lft.vR[i + 1].second
                                                    : lft.vL[0].second - 1)) *
                (rht.vR[0].second - rht.vL[j].second + 1LL);
  }
}
inline int seg_idx(int L, int R) { return (L + R) | (L < R); }
void seg_build(int L, int R) {
  Segment &rt = seg[seg_idx(L, R)];
  if (L == R) {
    int val;
    scanf("%d", &val);
    rt.cL = rt.cR = 1;
    rt.vL[0] = rt.vR[0] = (pair<int, int>){val, L};
    rt.sum = val >= x;
  } else {
    int M = (L + R) >> 1;
    seg_build(L, M);
    seg_build(M + 1, R);
    seg_up(rt, seg[seg_idx(L, M)], seg[seg_idx(M + 1, R)]);
  }
}
void seg_upd(int L, int R, int u, int v) {
  Segment &rt = seg[seg_idx(L, R)];
  if (L == R) {
    rt.cL = rt.cR = 1;
    rt.vL[0] = rt.vR[0] = (pair<int, int>){v, L};
    rt.sum = v >= x;
  } else {
    int M = (L + R) >> 1;
    if (u <= M)
      seg_upd(L, M, u, v);
    else
      seg_upd(M + 1, R, u, v);
    seg_up(rt, seg[seg_idx(L, M)], seg[seg_idx(M + 1, R)]);
  }
}
Segment seg_que(int L, int R, int u, int v) {
  Segment ret = {};
  if (u <= L && R <= v) {
    ret = seg[seg_idx(L, R)];
  } else {
    int M = (L + R) >> 1;
    if (v <= M) {
      ret = seg_que(L, M, u, v);
    } else if (u > M) {
      ret = seg_que(M + 1, R, u, v);
    } else {
      Segment lft = seg_que(L, M, u, v);
      Segment rht = seg_que(M + 1, R, u, v);
      seg_up(ret, lft, rht);
    }
  }
  return ret;
}
int main() {
  scanf("%d%d%d", &n, &m, &x);
  seg_build(1, n);
  while (m--) {
    int typ, x, y;
    scanf("%d%d%d", &typ, &x, &y);
    if (typ == 1) {
      seg_upd(1, n, x, y);
    } else {
      Segment res = seg_que(1, n, x, y);
      printf("%lld\n", res.sum);
    }
  }
  return 0;
}
