#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 100, OO = 1e6 + 1000, M = 1e9 + 7, P = 6151,
                SQ = 1000, lg = 44;
long long a[N], n, m, x;
struct node {
  long long ans = 0, bor = 0;
  vector<pair<long long, long long> > suf, pre;
} seg[N << 2];
void cmb(long long c) {
  seg[c].ans = seg[c << 1].ans + seg[c << 1 | 1].ans;
  seg[c].bor = seg[c << 1].bor | seg[c << 1 | 1].bor;
  for (auto u : seg[c << 1].suf)
    for (auto t : seg[c << 1 | 1].pre)
      if ((t.first | u.first) >= x) seg[c].ans += t.second * u.second;
  seg[c].pre = seg[c << 1].pre;
  seg[c].suf = seg[c << 1 | 1].suf;
  for (auto u : seg[c << 1 | 1].pre) {
    long long t = u.first | seg[c << 1].bor;
    if (seg[c].pre.empty() || (t & (seg[c].pre.back().first)) != t)
      seg[c].pre.push_back({t, u.second});
    else
      seg[c].pre.back().second += u.second;
  }
  for (auto u : seg[c << 1].suf) {
    long long t = u.first | seg[c << 1 | 1].bor;
    if (seg[c].suf.empty() || (t & (seg[c].suf.back().first)) != t)
      seg[c].suf.push_back({t, u.second});
    else
      seg[c].suf.back().second += u.second;
  }
}
void build(long long c, long long b, long long e) {
  if (e - b == 1) {
    seg[c].ans = (a[b] >= x);
    seg[c].pre.push_back({a[b], 1});
    seg[c].suf.push_back({a[b], 1});
    seg[c].bor = a[b];
    return;
  }
  long long mid = (b + e) >> 1;
  build(c << 1, b, mid);
  build(c << 1 | 1, mid, e);
  cmb(c);
}
void upd(long long c, long long b, long long e, long long l) {
  if (l < b || l >= e) return;
  if (e - b == 1) {
    seg[c].ans = (a[b] >= x);
    seg[c].pre.clear();
    seg[c].suf.clear();
    seg[c].pre.push_back({a[b], 1});
    seg[c].suf.push_back({a[b], 1});
    seg[c].bor = a[b];
    return;
  }
  long long mid = (b + e) >> 1;
  upd(c << 1, b, mid, l);
  upd(c << 1 | 1, mid, e, l);
  cmb(c);
}
node cmb2(node &a1, node &a2) {
  node ac;
  ac.ans = a1.ans + a2.ans;
  ac.bor = a1.bor | a2.bor;
  for (auto u : a1.suf)
    for (auto t : a2.pre)
      if ((t.first | u.first) >= x) ac.ans += t.second * u.second;
  ac.pre = a1.pre;
  ac.suf = a2.suf;
  for (auto u : a2.pre) {
    long long t = u.first | a1.bor;
    if (ac.pre.empty() || (t & (ac.pre.back().first)) != t)
      ac.pre.push_back({t, u.second});
    else
      ac.pre.back().second += u.second;
  }
  for (auto u : a1.suf) {
    long long t = u.first | a2.bor;
    if (ac.suf.empty() || (t & (ac.suf.back().first)) != t)
      ac.suf.push_back({t, u.second});
    else
      ac.suf.back().second += u.second;
  }
  return ac;
}
node get(long long c, long long b, long long e, long long l, long long r) {
  if (b == l && r == e) return seg[c];
  long long mid = (b + e) >> 1;
  if (r <= mid) return get(c << 1, b, mid, l, r);
  if (l >= mid) return get(c << 1 | 1, mid, e, l, r);
  node a1 = get(c << 1, b, mid, l, mid), a2 = get(c << 1 | 1, mid, e, mid, r);
  node t1 = cmb2(a1, a2);
  return t1;
}
int32_t main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m >> x;
  for (long long i = 0; i < n; i++) cin >> a[i];
  build(1, 0, n);
  while (m--) {
    long long t, l, r;
    cin >> t >> l >> r;
    if (t == 1) {
      a[l - 1] = r;
      upd(1, 0, n, l - 1);
    } else
      cout << get(1, 0, n, l - 1, r).ans << endl;
  }
  return 0;
}
