#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline T1 max(T1 a, T2 b) {
  return a < b ? b : a;
}
template <typename T1, typename T2>
inline T1 min(T1 a, T2 b) {
  return a < b ? a : b;
}
const char lf = '\n';
namespace ae86 {
const int bufl = 1 << 15;
char buf[bufl], *s = buf, *t = buf;
inline int fetch() {
  if (s == t) {
    t = (s = buf) + fread(buf, 1, bufl, stdin);
    if (s == t) return EOF;
  }
  return *s++;
}
inline int ty() {
  int a = 0;
  int b = 1, c = fetch();
  while (!isdigit(c)) b ^= c == '-', c = fetch();
  while (isdigit(c)) a = a * 10 + c - 48, c = fetch();
  return b ? a : -a;
}
}  // namespace ae86
using ae86::ty;
const int _ = 100007;
int tar;
struct cxk {
  vector<pair<int, int>> l, r;
  long long ans;
  cxk(int bas) {
    l = r = vector<pair<int, int>>(1, make_pair(bas, 1)), ans = bas >= tar;
  }
  cxk(vector<pair<int, int>> l_ = vector<pair<int, int>>(),
      vector<pair<int, int>> r_ = vector<pair<int, int>>(),
      long long ans_ = 0) {
    l = l_, r = r_, ans = ans_;
  }
  friend long long getans(cxk a, cxk b) {
    long long ans = 0;
    for (auto i : a.r)
      for (auto j : b.l)
        if ((i.first | j.first) >= tar) ans += 1ll * i.second * j.second;
    return ans;
  }
  friend cxk operator+(cxk a, cxk b) {
    if (a.l.empty()) return b;
    if (b.l.empty()) return a;
    cxk c;
    c.ans = a.ans + b.ans + getans(a, b);
    c.r = b.r;
    int now = b.r.back().first;
    for (auto i : a.r) {
      if ((i.first | now) == now)
        c.r.back().second += i.second;
      else
        c.r.emplace_back(now = (i.first | now), i.second);
    }
    c.l = a.l;
    now = a.l.back().first;
    for (auto i : b.l) {
      if ((i.first | now) == now)
        c.l.back().second += i.second;
      else
        c.l.emplace_back(now = (i.first | now), i.second);
    }
    return c;
  }
};
struct sgt {
  static const int _t = _ << 2;
  cxk t[_t];
  void up(int x) { t[x] = t[(x << 1)] + t[(x << 1 | 1)]; }
  void plant(int x, int l, int r, int val[]) {
    if (l == r) {
      t[x] = cxk(val[l]);
      return;
    }
    plant((x << 1), l, ((l + r) >> 1), val),
        plant((x << 1 | 1), ((l + r) >> 1) + 1, r, val), up(x);
  }
  void change(int x, int l, int r, int tar, int dlt) {
    if (l == r) {
      t[x] = cxk(dlt);
      return;
    }
    if (tar <= ((l + r) >> 1))
      change((x << 1), l, ((l + r) >> 1), tar, dlt);
    else
      change((x << 1 | 1), ((l + r) >> 1) + 1, r, tar, dlt);
    up(x);
  }
  cxk finder(int x, int l, int r, int tl, int tr) {
    if (tl <= l && r <= tr) return t[x];
    if (tr <= ((l + r) >> 1))
      return finder((x << 1), l, ((l + r) >> 1), tl, tr);
    if (tl > ((l + r) >> 1))
      return finder((x << 1 | 1), ((l + r) >> 1) + 1, r, tl, tr);
    return finder((x << 1), l, ((l + r) >> 1), tl, tr) +
           finder((x << 1 | 1), ((l + r) >> 1) + 1, r, tl, tr);
  }
} t;
int n, m, val[_];
int main() {
  ios::sync_with_stdio(0), cout.tie(nullptr);
  n = ty(), m = ty(), tar = ty();
  for (int i = 1; i <= n; i++) val[i] = ty();
  t.plant(1, 1, n, val);
  for (int qq = 1; qq <= m; qq++) {
    int op = ty();
    if (op == 1) {
      int a = ty(), b = ty();
      t.change(1, 1, n, a, b);
    }
    if (op == 2) {
      int a = ty(), b = ty();
      cout << t.finder(1, 1, n, a, b).ans << lf;
    }
  }
  return 0;
}
