#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

struct node
{
	node *left, *right;
	int y, cnt, v, upd;
	ll sm;

	node(int v) : left(0), right(0), y((rand() << 16) ^ rand()), cnt(1), v(v), sm(v), upd(-1) {};
};

typedef node* treap;
typedef pair<treap, treap> ptt;

int tree[sze << 1];

void push(treap cur)
{
	if (!cur || cur->upd == -1)
		return;

	if (cur->left)
		cur->left->upd = cur->upd;

	if (cur->right)
		cur->right->upd = cur->upd;

	cur->v = cur->upd;
	cur->sm = ll(cur->cnt) * cur->upd;
	cur->upd = -1;
}

int get(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->cnt;
}

ll get_sm(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->sm;
}

treap update(treap cur)
{
	push(cur);
	cur->cnt = 1 + get(cur->left) + get(cur->right);
	cur->sm = get_sm(cur->left) + get_sm(cur->right) + cur->v;
	return cur;
}

treap merge(treap L, treap R)
{
	push(L);
	push(R);

	if (!L)
		return R;

	if (!R)
		return L;

	if (L->y > R->y)
	{
		L->right = merge(L->right, R);
		return update(L);
	}
	else
	{
		R->left = merge(L, R->left);
		return update(R);
	}
}

ptt split(treap cur, int x)
{
	push(cur);

	if (!cur)
		return { cur, cur };

	int cur_x = get(cur->left);

	if (cur_x <= x)
	{
		ptt ans = split(cur->right, x - cur_x - 1);
		cur->right = ans.first;

		return { update(cur), ans.second };
	}
	else
	{
		ptt ans = split(cur->left, x);
		cur->left = ans.second;

		return { ans.first, update(cur) };
	}
}

int count(int v)
{
	int cnt = 0;
	for (int i = 0; i < psze; ++i)
		if (v & (1 << i))
			cnt++;

	return cnt;
}

int get(int l, int r, int lb, int rb, int ind)
{
	assert(l >= 1);
	assert(r >= 1);

	if (l == lb && r == rb)
		return tree[ind];

	int m = (lb + rb) >> 1;
	int first = 0, second = 0;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int ind, int v)
{
	ind += sze;
	tree[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree[ind] = tree[ind << 1] | tree[ind << 1 | 1];
		ind >>= 1;
	}
}

int get_bit(int l, int r)
{
	int cnt = get(l + 1, r + 1, 1, sze, 1);
	return cnt;
}

int n, q, x;
int cur = 0, pos = 0;

void get_left(int l, int r, int lb, int rb, int ind)
{
	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((cur | tree[ind]) < x)
		{
			cur |= tree[ind];
			return;
		}

		if (lb == rb)
		{
			pos = lb;
			return;
		}

		if ((cur | tree[ind << 1]) >= x)
			get_left(l, m, l, m, ind << 1);
		else
		{
			cur |= tree[ind << 1];
			get_left(m + 1, r, m + 1, r, ind << 1 | 1);
		}
	}

	if (l <= m && !pos)
		get_left(l, min(m, r), lb, m, ind << 1);

	if (r > m && !pos)
		get_left(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

}

int find(int i)
{
	cur = 0, pos = 0;
	get_left(i + 1, n, 1, sze, 1);

	int ans = !pos ? n : pos - 1;
	return ans;
}

char counting[1 << 20];

int get_get(int l, int r, int lb, int rb, int ind, int v)
{
	assert(l >= 1);
	assert(r >= 1);

	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree[ind] | v) == v)
			return -1;

		if (lb == rb)
			return lb - 1;

		if ((tree[ind << 1 | 1] | v) != v)
			return get_get(m + 1, rb, m + 1, rb, ind << 1 | 1, v);
		else
			return get_get(lb, m, lb, m, ind << 1, v);
	}

	int first = -1, second = -1;

	if (r > m && (tree[ind << 1 | 1] | v) != v)
		second = get_get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	if (second == -1 && l <= m && (tree[ind << 1] | v) != v)
		first = get_get(l, min(m, r), lb, m, ind << 1, v);

	return max(first, second);
}

int find_pos(int l, int r, int v)
{
	return get_get(l, r, 1, sze, 1, v);
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	srand(time(0));
	for (int i = 0; i < (1 << 20); ++i)
		counting[i] = count(i);

	cin >> n >> q >> x;
	vector<int> values(n);

	treap root = 0;

	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] | tree[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
			root = merge(root, new node(i));
		else
			root = merge(root, new node(find(i)));
	}

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			ind--;

			update(ind, v);
			int prev = ind;
			int ccccc = 0;

			while (prev >= 0 && v < x)
			{
				ccccc++;
				int l = find_pos(1, prev + 1, v);
				int r = l + 1;

				ptt F1 = split(root, prev);
				ptt F2 = split(F1.first, r - 1);
				F2.second->upd = find(r);
				root = merge(merge(F2.first, F2.second), F1.second);

				prev = l;
				if (prev >= 0)
					v = get_bit(l, ind);

				assert(ccccc < 30);
			}

			if (prev >= 0)
			{
				ptt F1 = split(root, prev);

				int l = -1, r = F1.first->cnt;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					ptt F11 = split(F1.first, m);
					ptt F22 = split(F11.first, m - 1);

					if (F22.second->v >= ind + 1)
						r = m;
					else
						l = m;

					F1.first = merge(merge(F22.first, F22.second), F11.second);
				}

				ptt F2 = split(F1.first, l);

				if (F2.second)
					F2.second->upd = ind;

				root = merge(merge(F2.first, F2.second), F1.second);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;
			l--, r--;

			ptt F1 = split(root, r);
			ptt F2 = split(F1.first, l - 1);

			int lb = -1, rb = F2.second->cnt;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;
				ptt F11 = split(F2.second, m);
				ptt F22 = split(F11.first, m - 1);

				if (F22.second->v > r + 1)
					rb = m;
				else
					lb = m;

				F2.second = merge(merge(F22.first, F22.second), F11.second);
			}

			ptt F11 = split(F2.second, rb - 1);
			ll a = 0;
			ll b = 0;

			if (F11.first)
				a = F11.first->sm;

			if (F11.second)
				b = ll(F11.second->cnt) * (r + 1);

			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 1) * (r - l + 2) / 2;

			ll ans = d - (a + b - c);
			cout << ans << '\n';

			F2.second = merge(F11.first, F11.second);
			root = merge(merge(F2.first, F2.second), F1.second);
		}//1
	}

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

struct node
{
	node *left, *right;
	int y, cnt, v, upd;
	ll sm;

	node(int v) : left(0), right(0), y((rand() << 16) ^ rand()), cnt(1), v(v), sm(v), upd(-1) {};
};

typedef node* treap;
typedef pair<treap, treap> ptt;

int tree[sze << 1];

void push(treap cur)
{
	if (!cur || cur->upd == -1)
		return;

	if (cur->left)
		cur->left->upd = cur->upd;

	if (cur->right)
		cur->right->upd = cur->upd;

	cur->v = cur->upd;
	cur->sm = ll(cur->cnt) * cur->upd;
	cur->upd = -1;
}

int get(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->cnt;
}

ll get_sm(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->sm;
}

treap update(treap cur)
{
	push(cur);
	cur->cnt = 1 + get(cur->left) + get(cur->right);
	cur->sm = get_sm(cur->left) + get_sm(cur->right) + cur->v;
	return cur;
}

treap merge(treap L, treap R)
{
	push(L);
	push(R);

	if (!L)
		return R;

	if (!R)
		return L;

	if (L->y > R->y)
	{
		L->right = merge(L->right, R);
		return update(L);
	}
	else
	{
		R->left = merge(L, R->left);
		return update(R);
	}
}

ptt split(treap cur, int x)
{
	push(cur);

	if (!cur)
		return { cur, cur };

	int cur_x = get(cur->left);

	if (cur_x <= x)
	{
		ptt ans = split(cur->right, x - cur_x - 1);
		cur->right = ans.first;

		return { update(cur), ans.second };
	}
	else
	{
		ptt ans = split(cur->left, x);
		cur->left = ans.second;

		return { ans.first, update(cur) };
	}
}

int count(int v)
{
	int cnt = 0;
	for (int i = 0; i < psze; ++i)
		if (v & (1 << i))
			cnt++;

	return cnt;
}

int get(int l, int r, int lb, int rb, int ind)
{
	assert(l >= 1);
	assert(r >= 1);

	if (l == lb && r == rb)
		return tree[ind];

	int m = (lb + rb) >> 1;
	int first = 0, second = 0;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int ind, int v)
{
	ind += sze;
	tree[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree[ind] = tree[ind << 1] | tree[ind << 1 | 1];
		ind >>= 1;
	}
}

int get_bit(int l, int r)
{
	int cnt = get(l + 1, r + 1, 1, sze, 1);
	return cnt;
}

int n, q, x;

int find(int i)
{
	int l = i, r = n;

	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (get_bit(i, m) >= x)
			r = m;
		else
			l = m;
	}

	return r;
}

char counting[1 << 20];

int get_get(int l, int r, int lb, int rb, int ind, int v)
{
	assert(l >= 1);
	assert(r >= 1);

	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree[ind] | v) == v)
			return -1;

		if (lb == rb)
			return lb - 1;

		if ((tree[ind << 1 | 1] | v) != v)
			return get_get(m + 1, rb, m + 1, rb, ind << 1 | 1, v);
		else
			return get_get(lb, m, lb, m, ind << 1, v);
	}

	int first = -1, second = -1;

	if (l <= m)
		first = get_get(l, min(m, r), lb, m, ind << 1, v);

	if (r > m)
		second = get_get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	return max(first, second);
}

int find_pos(int l, int r, int v)
{
	return get_get(l, r, 1, sze, 1, v);
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	srand(time(0));
	for (int i = 0; i < (1 << 20); ++i)
		counting[i] = count(i);

	cin >> n >> q >> x;
	vector<int> values(n);

	treap root = 0;

	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] | tree[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
			root = merge(root, new node(i));
		else
			root = merge(root, new node(find(i)));
	}

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			ind--;

			update(ind, v);
			int prev = ind;

			while (prev >= 0 && v < x)
			{
				int l = find_pos(1, prev + 1, v);
				int r = l + 1;

				ptt F1 = split(root, prev);
				ptt F2 = split(F1.first, r - 1);
				F2.second->upd = find(r);
				root = merge(merge(F2.first, F2.second), F1.second);

				prev = l;
				if (prev >= 0)
					v = get_bit(l, ind);
			}

			if (prev >= 0)
			{
				ptt F1 = split(root, prev);

				int l = -1, r = F1.first->cnt;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					ptt F11 = split(F1.first, m);
					ptt F22 = split(F11.first, m - 1);

					if (F22.second->v >= ind + 1)
						r = m;
					else
						l = m;

					F1.first = merge(merge(F22.first, F22.second), F11.second);
				}

				ptt F2 = split(F1.first, l);

				if (F2.second)
					F2.second->upd = ind;

				root = merge(merge(F2.first, F2.second), F1.second);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;
			l--, r--;

			ptt F1 = split(root, r);
			ptt F2 = split(F1.first, l - 1);

			int lb = -1, rb = F2.second->cnt;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;
				ptt F11 = split(F2.second, m);
				ptt F22 = split(F11.first, m - 1);

				if (F22.second->v > r + 1)
					rb = m;
				else
					lb = m;

				F2.second = merge(merge(F22.first, F22.second), F11.second);
			}

			ptt F11 = split(F2.second, rb - 1);
			ll a = 0;
			ll b = 0;

			if (F11.first)
				a = F11.first->sm;

			if (F11.second)
				b = ll(F11.second->cnt) * (r + 1);

			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 1) * (r - l + 2) / 2;

			ll ans = d - (a + b - c);
			cout << ans << '\n';

			F2.second = merge(F11.first, F11.second);
			root = merge(merge(F2.first, F2.second), F1.second);
		}
	}

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

struct node
{
	node *left, *right;
	int y, cnt, v, upd;
	ll sm;

	node(int v) : left(0), right(0), y((rand() << 16) ^ rand()), cnt(1), v(v), sm(v), upd(-1) {};
};

typedef node* treap;
typedef pair<treap, treap> ptt;

int tree[sze << 1];

void push(treap cur)
{
	if (!cur || cur->upd == -1)
		return;

	if (cur->left)
		cur->left->upd = cur->upd;

	if (cur->right)
		cur->right->upd = cur->upd;

	cur->v = cur->upd;
	cur->sm = ll(cur->cnt) * cur->upd;
	cur->upd = -1;
}

int get(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->cnt;
}

ll get_sm(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->sm;
}

treap update(treap cur)
{
	push(cur);
	cur->cnt = 1 + get(cur->left) + get(cur->right);
	cur->sm = get_sm(cur->left) + get_sm(cur->right) + cur->v;
	return cur;
}

treap merge(treap L, treap R)
{
	push(L);
	push(R);

	if (!L)
		return R;

	if (!R)
		return L;

	if (L->y > R->y)
	{
		L->right = merge(L->right, R);
		return update(L);
	}
	else
	{
		R->left = merge(L, R->left);
		return update(R);
	}
}

ptt split(treap cur, int x)
{
	push(cur);

	if (!cur)
		return { cur, cur };

	int cur_x = get(cur->left);

	if (cur_x <= x)
	{
		ptt ans = split(cur->right, x - cur_x - 1);
		cur->right = ans.first;

		return { update(cur), ans.second };
	}
	else
	{
		ptt ans = split(cur->left, x);
		cur->left = ans.second;

		return { ans.first, update(cur) };
	}
}

int count(int v)
{
	int cnt = 0;
	for (int i = 0; i < psze; ++i)
		if (v & (1 << i))
			cnt++;

	return cnt;
}

int get(int l, int r, int lb, int rb, int ind)
{
	assert(l >= 1);
	assert(r >= 1);

	if (l == lb && r == rb)
		return tree[ind];

	int m = (lb + rb) >> 1;
	int first = 0, second = 0;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int ind, int v)
{
	ind += sze;
	tree[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree[ind] = tree[ind << 1] | tree[ind << 1 | 1];
		ind >>= 1;
	}
}

int get_bit(int l, int r)
{
	int cnt = get(l + 1, r + 1, 1, sze, 1);
	return cnt;
}

int n, q, x;

int find(int i)
{
	int l = i, r = n;

	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (get_bit(i, m) >= x)
			r = m;
		else
			l = m;
	}

	return r;
}

char counting[1 << 20];

int get_get(int l, int r, int lb, int rb, int ind, int v)
{
	assert(l >= 1);
	assert(r >= 1);

	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree[ind] | v) == v)
			return -1;

		if (lb == rb)
			return lb - 1;

		if ((tree[ind << 1 | 1] | v) != v)
			return get_get(m + 1, rb, m + 1, rb, ind << 1 | 1, v);
		else
			return get_get(lb, m, lb, m, ind << 1, v);
	}

	int first = -1, second = -1;

	if (l <= m)
		first = get_get(l, min(m, r), lb, m, ind << 1, v);

	if (r > m)
		second = get_get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	return max(first, second);
}

int find_pos(int l, int r, int v)
{
	return get_get(l, r, 1, sze, 1, v);
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	for (int i = 0; i < (1 << 20); ++i)
		counting[i] = count(i);

	cin >> n >> q >> x;
	vector<int> values(n);

	treap root = 0;

	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] | tree[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
			root = merge(root, new node(i));
		else
			root = merge(root, new node(find(i)));
	}

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			ind--;

			update(ind, v);
			int prev = ind;

			while (prev >= 0 && v < x)
			{
				int l = find_pos(1, prev + 1, v);
				int r = l + 1;

				ptt F1 = split(root, prev);
				ptt F2 = split(F1.first, r - 1);
				F2.second->upd = find(r);
				root = merge(merge(F2.first, F2.second), F1.second);

				prev = l;
				if (prev >= 0)
					v = get_bit(l, ind);
			}

			if (prev >= 0)
			{
				ptt F1 = split(root, prev);

				int l = -1, r = F1.first->cnt;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					ptt F11 = split(F1.first, m);
					ptt F22 = split(F11.first, m - 1);

					if (F22.second->v >= ind + 1)
						r = m;
					else
						l = m;

					F1.first = merge(merge(F22.first, F22.second), F11.second);
				}

				ptt F2 = split(F1.first, l);

				if (F2.second)
					F2.second->upd = ind;

				root = merge(merge(F2.first, F2.second), F1.second);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;
			l--, r--;

			ptt F1 = split(root, r);
			ptt F2 = split(F1.first, l - 1);

			int lb = -1, rb = F2.second->cnt;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;
				ptt F11 = split(F2.second, m);
				ptt F22 = split(F11.first, m - 1);

				if (F22.second->v > r + 1)
					rb = m;
				else
					lb = m;

				F2.second = merge(merge(F22.first, F22.second), F11.second);
			}

			ptt F11 = split(F2.second, rb - 1);
			ll a = 0;
			ll b = 0;

			if (F11.first)
				a = F11.first->sm;

			if (F11.second)
				b = ll(F11.second->cnt) * (r + 1);

			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 1) * (r - l + 2) / 2;

			ll ans = d - (a + b - c);
			cout << ans << '\n';

			F2.second = merge(F11.first, F11.second);
			root = merge(merge(F2.first, F2.second), F1.second);
		}
	}

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

int tree_or[sze << 1], updating[sze << 1];
ll tree[sze << 1];

int n, q, x;

int first_large(int l, int r, int lb, int rb, int ind, int &cur)
{
	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree_or[ind] | cur) < x)
		{
			cur |= tree_or[ind];
			return sze;
		}

		if (lb == rb)
		{
			cur |= tree_or[ind];
			return lb;
		}

		if ((cur | tree_or[ind << 1]) >= x)
			return first_large(l, m, l, m, ind << 1, cur);
		else
		{
			cur |= tree_or[ind << 1];
			return first_large(m + 1, r, m + 1, r, ind << 1 | 1, cur);
		}
	}

	int first = sze, second = sze;
	assert(cur < x);

	if (l <= m)
		first = first_large(l, min(m, r), lb, m, ind << 1, cur);

	if (r > m && cur < x)
	{
		second = first_large(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, cur);
		assert(first == sze);
	}

	if (first == sze)
		return second;

	if (second == sze)
		return first;

	return min(first, second);
}

void push(int ind, ll len)
{
	if (updating[ind] == -1)
		return;

	tree[ind] = len * updating[ind];

	if (len != 1)
		updating[ind << 1] = updating[ind << 1 | 1] = updating[ind];

	updating[ind] = -1;
}

ll get(int l, int r, int lb, int rb, int ind)
{
	push(ind, rb - lb + 1);

	if (l == lb && r == rb)
		return tree[ind];

	ll first = 0, second = 0;
	int m = (lb + rb) >> 1;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	push(ind << 1, rb - m);
	push(ind << 1 | 1, rb - m);
	tree[ind] = tree[ind << 1] + tree[ind << 1 | 1];

	return first + second;
}

void update_or(int ind, int v)
{
	ind += sze - 1;
	tree_or[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree_or[ind] = tree_or[ind << 1] | tree_or[ind << 1 | 1];
		ind >>= 1;
	}
}

int bits(int l, int r, int lb, int rb, int ind, int v)
{
	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree_or[ind] | v) == v)
			return 0;

		if (lb == rb)
			return lb;

		if ((tree_or[ind << 1 | 1] | v) != v)
			return bits(m + 1, r, m + 1, r, ind << 1 | 1, v);
		else
			return bits(l, m, l, m, ind << 1, v);
	}

	int first = 0, second = 0;

	if (r > m)
		second = bits(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	if (!second && l <= m)
		first = bits(l, min(m, r), lb, m, ind << 1, v);

	return max(first, second);
}

int get_or(int l, int r, int lb, int rb, int ind)
{
	if (l == lb && r == rb)
		return tree_or[ind];

	int first = 0, second = 0;
	int m = (lb + rb) >> 1;

	if (l <= m)
		first = get_or(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get_or(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int l, int r, int lb, int rb, int ind, int v)
{
	push(ind, rb - lb + 1);

	if (l == lb && r == rb)
	{
		updating[ind] = v;
		push(ind, rb - lb + 1);
		return;
	}

	int m = (lb + rb) >> 1;

	if (l <= m)
		update(l, min(m, r), lb, m, ind << 1, v);

	if (r > m)
		update(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	push(ind << 1, rb - m);
	push(ind << 1 | 1, rb - m);
	tree[ind] = tree[ind << 1] + tree[ind << 1 | 1];
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> n >> q >> x;

	vector<int> values(n);
	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree_or[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree_or[i] = tree_or[i << 1] | tree_or[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
		{
			tree[i + sze] = i + 1;
			continue;
		}

		int c = 0;
		tree[i + sze] = first_large(i + 1, sze, 1, sze, 1, c);
	}

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] + tree[i << 1 | 1];

	fill(updating, updating + (sze << 1), -1);

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			update_or(ind, v);

			int prev = ind;
			while (prev && v < x)
			{
				int c = 0;
				int ind_new = bits(1, prev, 1, sze, 1, v);
				int pos = first_large(ind_new + 1, sze, 1, sze, 1, c);

				update(ind_new + 1, prev, 1, sze, 1, pos);

				if (ind_new)
					v = get_or(ind_new, ind, 1, sze, 1);

				prev = ind_new;
			}

			if (prev)
			{
				int l = 0, r = prev + 1;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					if (get(m, m, 1, sze, 1) > ind)
						r = m;
					else
						l = m;
				}

				if (r != prev + 1)
					update(r, prev, 1, sze, 1, ind);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;

			int lb = l - 1, rb = r + 1;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;

				if (get(m, m, 1, sze, 1) > r + 1)
					rb = m;
				else
					lb = m;
			}

			ll a = 0;

			if (lb != l - 1)
				a = get(l, lb, 1, sze, 1);

			ll b = ll(r + 1 - rb) * (r + 1);
			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 2) * (r - l + 1) / 2;

			cout << d - (a + b - c) << '\n';
		}
	}

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

int tree_or[sze << 1], updating[sze << 1];
ll tree[sze << 1];

int n, q, x;

int first_large(int l, int r, int lb, int rb, int ind, int &cur)
{
	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree_or[ind] | cur) < x)
		{
			cur |= tree_or[ind];
			return sze;
		}

		if (lb == rb)
		{
			cur |= tree_or[ind];
			return lb;
		}

		if ((cur | tree_or[ind << 1]) >= x)
			return first_large(l, m, l, m, ind << 1, cur);
		else
		{
			cur |= tree_or[ind << 1];
			return first_large(m + 1, r, m + 1, r, ind << 1 | 1, cur);
		}
	}

	int first = sze, second = sze;
	assert(cur < x);

	if (l <= m)
		first = first_large(l, min(m, r), lb, m, ind << 1, cur);

	if (r > m && cur < x)
	{
		second = first_large(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, cur);
		assert(first == sze);
	}

	if (first == sze)
		return second;

	if (second == sze)
		return first;

	return min(first, second);
}

void push(int ind, ll len)
{
	if (updating[ind] == -1)
		return;

	tree[ind] = len * updating[ind];

	if (len != 1)
		updating[ind << 1] = updating[ind << 1 | 1] = updating[ind];
}

ll get(int l, int r, int lb, int rb, int ind)
{
	push(ind, rb - lb + 1);

	if (l == lb && r == rb)
		return tree[ind];

	ll first = 0, second = 0;
	int m = (lb + rb) >> 1;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	push(ind << 1, rb - m);
	push(ind << 1 | 1, rb - m);
	tree[ind] = tree[ind << 1] + tree[ind << 1 | 1];

	return first + second;
}

void update_or(int ind, int v)
{
	ind += sze - 1;
	tree_or[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree_or[ind] = tree_or[ind << 1] | tree_or[ind << 1 | 1];
		ind >>= 1;
	}
}

int bits(int l, int r, int lb, int rb, int ind, int v)
{
	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree_or[ind] | v) == v)
			return 0;

		if (lb == rb)
			return lb;

		if ((tree_or[ind << 1 | 1] | v) != v)
			return bits(m + 1, r, m + 1, r, ind << 1 | 1, v);
		else
			return bits(l, m, l, m, ind << 1, v);
	}

	int first = 0, second = 0;

	if (r > m)
		second = bits(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	if (!second && l <= m)
		first = bits(l, min(m, r), lb, m, ind << 1, v);

	return max(first, second);
}

int get_or(int l, int r, int lb, int rb, int ind)
{
	if (l == lb && r == rb)
		return tree_or[ind];

	int first = 0, second = 0;
	int m = (lb + rb) >> 1;

	if (l <= m)
		first = get_or(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get_or(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int l, int r, int lb, int rb, int ind, int v)
{
	push(ind, rb - lb + 1);

	if (l == lb && r == rb)
	{
		updating[ind] = v;
		push(ind, rb - lb + 1);
		return;
	}

	int m = (lb + rb) >> 1;

	if (l <= m)
		update(l, min(m, r), lb, m, ind << 1, v);

	if (r > m)
		update(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	push(ind << 1, rb - m);
	push(ind << 1 | 1, rb - m);
	tree[ind] = tree[ind << 1] + tree[ind << 1 | 1];
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> n >> q >> x;

	vector<int> values(n);
	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree_or[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree_or[i] = tree_or[i << 1] | tree_or[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
		{
			tree[i + sze] = i + 1;
			continue;
		}

		int c = 0;
		tree[i + sze] = first_large(i + 1, sze, 1, sze, 1, c);
	}

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] + tree[i << 1 | 1];

	fill(updating, updating + (sze << 1), -1);

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			update_or(ind, v);

			int prev = ind;
			while (prev && v < x)
			{
				int c = 0;
				int ind_new = bits(1, prev, 1, sze, 1, v);
				int pos = first_large(ind_new + 1, sze, 1, sze, 1, c);

				update(ind_new + 1, prev, 1, sze, 1, pos);

				if (ind_new)
					v = get_or(ind_new, ind, 1, sze, 1);

				prev = ind_new;
			}

			if (prev)
			{
				int l = 0, r = prev + 1;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					if (get(m, m, 1, sze, 1) > ind)
						r = m;
					else
						l = m;
				}

				if (r != prev + 1)
					update(r, prev, 1, sze, 1, ind);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;

			int lb = l - 1, rb = r + 1;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;

				if (get(m, m, 1, sze, 1) > r + 1)
					rb = m;
				else
					lb = m;
			}

			ll a = 0;

			if (lb != l - 1)
				a = get(l, lb, 1, sze, 1);

			ll b = ll(r + 1 - rb) * (r + 1);
			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 2) * (r - l + 1) / 2;

			cout << d - (a + b - c) << '\n';
		}
	}

	return 0;
}


#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;

const int sze = 1 << 17, psze = 20;

struct node
{
	node *left, *right;
	int y, cnt, v, upd;
	ll sm;

	node(int v) : left(0), right(0), y((rand() << 16) ^ rand()), cnt(1), v(v), sm(v), upd(-1) {};
};

typedef node* treap;
typedef pair<treap, treap> ptt;

int tree[sze << 1];

void push(treap cur)
{
	if (!cur || cur->upd == -1)
		return;

	if (cur->left)
		cur->left->upd = cur->upd;

	if (cur->right)
		cur->right->upd = cur->upd;

	cur->v = cur->upd;
	cur->sm = ll(cur->cnt) * cur->upd;
	cur->upd = -1;
}

int get(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->cnt;
}

ll get_sm(treap cur)
{
	push(cur);
	return !cur ? 0 : cur->sm;
}

treap update(treap cur)
{
	push(cur);
	cur->cnt = 1 + get(cur->left) + get(cur->right);
	cur->sm = get_sm(cur->left) + get_sm(cur->right) + cur->v;
	return cur;
}

treap merge(treap L, treap R)
{
	push(L);
	push(R);

	if (!L)
		return R;

	if (!R)
		return L;

	if (L->y > R->y)
	{
		L->right = merge(L->right, R);
		return update(L);
	}
	else
	{
		R->left = merge(L, R->left);
		return update(R);
	}
}

ptt split(treap cur, int x)
{
	push(cur);

	if (!cur)
		return { cur, cur };

	int cur_x = get(cur->left);

	if (cur_x <= x)
	{
		ptt ans = split(cur->right, x - cur_x - 1);
		cur->right = ans.first;

		return { update(cur), ans.second };
	}
	else
	{
		ptt ans = split(cur->left, x);
		cur->left = ans.second;

		return { ans.first, update(cur) };
	}
}

int count(int v)
{
	int cnt = 0;
	for (int i = 0; i < psze; ++i)
		if (v & (1 << i))
			cnt++;

	return cnt;
}

int get(int l, int r, int lb, int rb, int ind)
{
	assert(l >= 1);
	assert(r >= 1);

	if (l == lb && r == rb)
		return tree[ind];

	int m = (lb + rb) >> 1;
	int first = 0, second = 0;

	if (l <= m)
		first = get(l, min(m, r), lb, m, ind << 1);

	if (r > m)
		second = get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1);

	return first | second;
}

void update(int ind, int v)
{
	ind += sze;
	tree[ind] = v;
	ind >>= 1;

	while (ind)
	{
		tree[ind] = tree[ind << 1] | tree[ind << 1 | 1];
		ind >>= 1;
	}
}

int get_bit(int l, int r)
{
	int cnt = get(l + 1, r + 1, 1, sze, 1);
	return cnt;
}

int n, q, x;

int find(int i)
{
	int l = i, r = n;

	while (r - l > 1)
	{
		int m = (l + r) >> 1;

		if (get_bit(i, m) >= x)
			r = m;
		else
			l = m;
	}

	return r;
}

char counting[1 << 20];

int get_get(int l, int r, int lb, int rb, int ind, int v)
{
	assert(l >= 1);
	assert(r >= 1);

	int m = (lb + rb) >> 1;

	if (l == lb && r == rb)
	{
		if ((tree[ind] | v) == v)
			return -1;

		if (lb == rb)
			return lb - 1;

		if ((tree[ind << 1 | 1] | v) != v)
			return get_get(m + 1, rb, m + 1, rb, ind << 1 | 1, v);
		else
			return get_get(lb, m, lb, m, ind << 1, v);
	}

	int first = -1, second = -1;

	if (r > m)
		second = get_get(max(l, m + 1), r, m + 1, rb, ind << 1 | 1, v);

	if (second == -1 && l <= m)
		first = get_get(l, min(m, r), lb, m, ind << 1, v);

	return max(first, second);
}

int find_pos(int l, int r, int v)
{
	return get_get(l, r, 1, sze, 1, v);
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	srand(time(0));
	for (int i = 0; i < (1 << 20); ++i)
		counting[i] = count(i);

	cin >> n >> q >> x;
	vector<int> values(n);

	treap root = 0;

	for (int i = 0; i < n; ++i)
		cin >> values[i];

	for (int i = 0; i < n; ++i)
		tree[i + sze] = values[i];

	for (int i = sze - 1; i; --i)
		tree[i] = tree[i << 1] | tree[i << 1 | 1];

	for (int i = 0; i < n; ++i)
	{
		if (values[i] >= x)
			root = merge(root, new node(i));
		else
			root = merge(root, new node(find(i)));
	}

	for (int i = 0; i < q; ++i)
	{
		int label;
		cin >> label;

		if (label == 1)
		{
			int ind, v;
			cin >> ind >> v;
			ind--;

			update(ind, v);
			int prev = ind;

			while (prev >= 0 && v < x)
			{
				int l = find_pos(1, prev + 1, v);
				int r = l + 1;

				ptt F1 = split(root, prev);
				ptt F2 = split(F1.first, r - 1);
				F2.second->upd = find(r);
				root = merge(merge(F2.first, F2.second), F1.second);

				prev = l;
				if (prev >= 0)
					v = get_bit(l, ind);
			}

			if (prev >= 0)
			{
				ptt F1 = split(root, prev);

				int l = -1, r = F1.first->cnt;
				while (r - l > 1)
				{
					int m = (l + r) >> 1;

					ptt F11 = split(F1.first, m);
					ptt F22 = split(F11.first, m - 1);

					if (F22.second->v >= ind + 1)
						r = m;
					else
						l = m;

					F1.first = merge(merge(F22.first, F22.second), F11.second);
				}

				ptt F2 = split(F1.first, l);

				if (F2.second)
					F2.second->upd = ind;

				root = merge(merge(F2.first, F2.second), F1.second);
			}
		}
		else
		{
			int l, r;
			cin >> l >> r;
			l--, r--;

			ptt F1 = split(root, r);
			ptt F2 = split(F1.first, l - 1);

			int lb = -1, rb = F2.second->cnt;
			while (rb - lb > 1)
			{
				int m = (lb + rb) >> 1;
				ptt F11 = split(F2.second, m);
				ptt F22 = split(F11.first, m - 1);

				if (F22.second->v > r + 1)
					rb = m;
				else
					lb = m;

				F2.second = merge(merge(F22.first, F22.second), F11.second);
			}

			ptt F11 = split(F2.second, rb - 1);
			ll a = 0;
			ll b = 0;

			if (F11.first)
				a = F11.first->sm;

			if (F11.second)
				b = ll(F11.second->cnt) * (r + 1);

			ll c = ll(l + r) * (r - l + 1) / 2;
			ll d = ll(r - l + 1) * (r - l + 2) / 2;

			ll ans = d - (a + b - c);
			cout << ans << '\n';

			F2.second = merge(F11.first, F11.second);
			root = merge(merge(F2.first, F2.second), F1.second);
		}
	}

	return 0;
}


#include <bits/stdc++.h>

#define FOR(i, x, y) for (int i = x; i <= y; i++)
#define ROF(i, x, y) for (int i = x; i >= y; i--)

int n, m, X;
const int N = 100001;
int a[N];
struct Node {
	long long cnt;
	std::vector<std::pair<int, int>> st, ed;
} tr[N << 2];
Node merge(Node x, Node y) {
	if (!x.ed.size())
		return y;
	if (!y.ed.size())
		return x;
	Node result;
	result.cnt = x.cnt + y.cnt;
	for (auto i : x.ed)
		for (auto j : y.st)
			if ((i.first | j.first) >= X)
				result.cnt += 1ll * i.second * j.second;
	result.st = x.st;
	int temp = result.st.back().first;
	for (auto i : y.st)
		if ((i.first | temp) == temp)
			result.st.back().second += i.second;
		else
			result.st.emplace_back(temp |= i.first, i.second);
	result.ed = y.ed;
	temp = result.ed.back().first;
	for (auto i : x.ed)
		if ((i.first | temp) == temp)
			result.ed.back().second += i.second;
		else
			result.ed.emplace_back(temp |= i.first, i.second);
	return result;
}

void pushup(int p) { tr[p] = merge(tr[p << 1], tr[p << 1 | 1]); }

void build(int l, int r, int p) {
	if (l == r) {
		tr[p].st.emplace_back(a[l], 1);
		tr[p].ed.emplace_back(a[l], 1);
		tr[p].cnt = (a[l] >= X) ? 1 : 0;
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, p << 1);
	build(mid + 1, r, p << 1 | 1);
	pushup(p);
}

void modify(int l, int r, int p, int x, int v) {
	if (l == r) {
		tr[p].st.clear();
		tr[p].ed.clear();
		tr[p].st.emplace_back(a[l], 1);
		tr[p].ed.emplace_back(a[l], 1);
		tr[p].cnt = (a[l] >= X) ? 1 : 0;
		return;
	}
	int mid = l + r >> 1;
	if (x <= mid)
		modify(l, mid, p << 1, x, v);
	else
		modify(mid + 1, r, p << 1 | 1, x, v);
	pushup(p);
}

Node query(int ql, int qr, int l, int r, int p) {
	if (ql <= l && r <= qr)
		return tr[p];
	int mid = l + r >> 1;
	Node result;
	if (ql <= mid)
		result = merge(result, query(ql, qr, l, mid, p << 1));
	if (qr > mid)
		result = merge(result, query(ql, qr, mid + 1, r, p << 1 | 1));
	return result;
}

int main() {
#ifdef LOCAL
	freopen("testdata.txt", "r", stdin);
#endif

	std::ios::sync_with_stdio(false);
	std::cin.tie(NULL);

	std::cin >> n >> m >> X;
	FOR(i, 1, n)
		std::cin >> a[i];
	build(1, n, 1);
	FOR(i, 1, m) {
		int op;
		std::cin >> op;
		if (op == 1) {
			int x, y;
			std::cin >> x >> y;
			a[x] = y;
			modify(1, n, 1, x, y);
		} else {
			int l, r;
			std::cin >> l >> r;
			std::cout << query(l, r, 1, n, 1).cnt << '\n';
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N=100000,C=21;

int n,cq,m,a[N+9];

void into(){
  scanf("%d%d%d",&n,&cq,&m);
  for (int i=1;i<=n;++i)
	scanf("%d",&a[i]);
}

int sum[C+9];
struct tree{

  vector<int>a[2],c[2];
  LL ans;

  tree(){ans=0;}

  tree(int x){
	a[0].clear();c[0].clear();
	a[1].clear();c[1].clear();
	a[0].push_back(x);
	c[0].push_back(1);
	a[1].push_back(x);
	c[1].push_back(1);
	ans=x>=m;
  }

  tree operator + (const tree &p)const{
	tree res;
	res.a[0]=a[0];res.c[0]=c[0];
	res.a[1]=p.a[1];res.c[1]=p.c[1];
	res.ans=ans+p.ans;
	for (int vs=p.a[0].size(),i=0,j=res.a[0].size()-1;i<vs;++i)
	  if ((p.a[0][i]|res.a[0][j])==res.a[0][j]) res.c[0][j]+=p.c[0][i];
      else res.a[0].push_back(p.a[0][i]|res.a[0][j]),res.c[0].push_back(p.c[0][i]),++j;
	for (int vs=a[1].size(),i=0,j=res.a[1].size()-1;i<vs;++i)
	  if ((a[1][i]|res.a[1][j])==res.a[1][j]) res.c[1][j]+=c[1][i];
      else res.a[1].push_back(a[1][i]|res.a[1][j]),res.c[1].push_back(c[1][i]),++j;
	for (int vs=p.a[0].size(),i=vs-1;i>=0;--i) sum[i]=i+1<vs?sum[i+1]+p.c[0][i]:p.c[0][i];
	for (int vs=a[1].size(),i=vs-1,j=0;i>=0;--i){
	  int lim=p.a[0].size();
	  for (;j<lim&&(a[1][i]|p.a[0][j])<m;++j);
	  if (j>=lim) break;
	  res.ans+=(LL)c[1][i]*sum[j];
	}
	return res;
  }

}tr[N*4+9];

void Build(int l,int r,int k){
  if (l==r) {tr[k]=tree(a[l]);return;}
  int mid=l+r>>1;
  Build(l,mid,k<<1);
  Build(mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

void Change(int p,int v,int l,int r,int k){
  if (l==r) {tr[k]=tree(v);return;}
  int mid=l+r>>1;
  p<=mid?Change(p,v,l,mid,k<<1):Change(p,v,mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

tree Query_ans(int L,int R,int l,int r,int k){
  if (L<=l&&R>=r) return tr[k];
  int mid=l+r>>1;
  if (R<=mid) return Query_ans(L,R,l,mid,k<<1);
  if (L>mid) return Query_ans(L,R,mid+1,r,k<<1|1);
  return Query_ans(L,R,l,mid,k<<1)+Query_ans(L,R,mid+1,r,k<<1|1);
}

void work(){
  Build(1,n,1);
}

void getans(){
  for (;cq--;){
	int opt,l,r;
	scanf("%d%d%d",&opt,&l,&r);
	if (opt==1) Change(l,r,1,n,1);
	else printf("%lld\n",Query_ans(l,r,1,n,1).ans);
  }
}

int main(){
  into();
  work();
  getans();
  return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N=100000,C=21;

int n,cq,m,a[N+9];

void into(){
  scanf("%d%d%d",&n,&cq,&m);
  for (int i=1;i<=n;++i)
	scanf("%d",&a[i]);
}

int sum[C+9];
struct tree{

  vector<int>a[2],c[2];
  LL ans;

  tree(){ans=0;}

  tree(int x){
	a[0].push_back(x);
	c[0].push_back(1);
	a[1].push_back(x);
	c[1].push_back(1);
	ans=x>=m;
  }

  tree operator + (const tree &p)const{
	tree res;
	res.a[0]=a[0];res.c[0]=c[0];
	res.a[1]=p.a[1];res.c[1]=p.c[1];
	res.ans=ans+p.ans;
	for (int vs=p.a[0].size(),i=0,j=res.a[0].size()-1;i<vs;++i)
	  if ((p.a[0][i]|res.a[0][j])==res.a[0][j]) res.c[0][j]+=p.c[0][i];
      else res.a[0].push_back(p.a[0][i]|res.a[0][j]),res.c[0].push_back(p.c[0][i]),++j;
	for (int vs=a[1].size(),i=0,j=res.a[1].size()-1;i<vs;++i)
	  if ((a[1][i]|res.a[1][j])==res.a[1][j]) res.c[1][j]+=c[1][i];
      else res.a[1].push_back(a[1][i]|res.a[1][j]),res.c[1].push_back(c[1][i]),++j;
	for (int vs=p.a[0].size(),i=vs-1;i>=0;--i) sum[i]=i+1<vs?sum[i+1]+p.c[0][i]:p.c[0][i];
	for (int vs=a[1].size(),i=vs-1,j=0;i>=0;--i){
	  int lim=p.a[0].size();
	  for (;j<lim&&(a[1][i]|p.a[0][j])<m;++j);
	  if (j>=lim) break;
	  res.ans+=(LL)c[1][i]*sum[j];
	}
	return res;
  }

}tr[N*4+9];

void Build(int l,int r,int k){
  if (l==r) {tr[k]=tree(a[l]);return;}
  int mid=l+r>>1;
  Build(l,mid,k<<1);
  Build(mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

void Change(int p,int v,int l,int r,int k){
  if (l==r) {tr[k]=tree(v);return;}
  int mid=l+r>>1;
  p<=mid?Change(p,v,l,mid,k<<1):Change(p,v,mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

tree Query_ans(int L,int R,int l,int r,int k){
  if (L<=l&&R>=r) return tr[k];
  int mid=l+r>>1;
  if (R<=mid) return Query_ans(L,R,l,mid,k<<1);
  if (L>mid) return Query_ans(L,R,mid+1,r,k<<1|1);
  return Query_ans(L,R,l,mid,k<<1)+Query_ans(L,R,mid+1,r,k<<1|1);
}

void work(){
  Build(1,n,1);
}

void getans(){
  for (;cq--;){
	int opt,l,r;
	scanf("%d%d%d",&opt,&l,&r);
	if (opt==1) Change(l,r,1,n,1);
	else printf("%lld\n",Query_ans(l,r,1,n,1).ans);
  }
}

int main(){
  freopen("mu.in","r",stdin);
  freopen("mu.out","w",stdout);
  into();
  work();
  getans();
  return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N=100000,C=21;

int n,cq,m,a[N+9];

void into(){
  scanf("%d%d%d",&n,&cq,&m);
  for (int i=1;i<=n;++i)
	scanf("%d",&a[i]);
}

int sum[C+9];
struct tree{

  vector<int>a[2],c[2];
  LL ans;

  tree(){ans=0;}

  tree(int x){
	a[0].push_back(x);
	c[0].push_back(1);
	a[1].push_back(x);
	c[1].push_back(1);
	ans=x>=m;
  }

  tree operator + (const tree &p)const{
	tree res;
	res.a[0]=a[0];res.c[0]=c[0];
	res.a[1]=p.a[1];res.c[1]=p.c[1];
	res.ans=ans+p.ans;
	for (int vs=p.a[0].size(),i=0,j=res.a[0].size()-1;i<vs;++i)
	  if ((p.a[0][i]|res.a[0][j])==res.a[0][j]) res.c[0][j]+=p.c[0][i];
      else res.a[0].push_back(p.a[0][i]|res.a[0][j]),res.c[0].push_back(p.c[0][i]),++j;
	for (int vs=a[1].size(),i=0,j=res.a[1].size()-1;i<vs;++i)
	  if ((a[1][i]|res.a[1][j])==res.a[1][j]) res.c[1][j]+=c[1][i];
      else res.a[1].push_back(a[1][i]|res.a[1][j]),res.c[1].push_back(c[1][i]),++j;
	for (int vs=p.a[0].size(),i=vs-1;i>=0;--i) sum[i]=i+1<vs?sum[i+1]+p.c[0][i]:p.c[0][i];
	for (int vs=a[1].size(),i=vs-1,j=0;i>=0;--i){
	  int lim=p.a[0].size();
	  for (;j<lim&&(a[1][i]|p.a[0][j])<m;++j);
	  if (j>=lim) break;
	  res.ans+=(LL)c[1][i]*sum[j];
	}
	return res;
  }

}tr[N*4+9];

void Build(int l,int r,int k){
  if (l==r) {tr[k]=tree(a[l]);return;}
  int mid=l+r>>1;
  Build(l,mid,k<<1);
  Build(mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

void Change(int p,int v,int l,int r,int k){
  if (l==r) {tr[k]=tree(v);return;}
  int mid=l+r>>1;
  p<=mid?Change(p,v,l,mid,k<<1):Change(p,v,mid+1,r,k<<1|1);
  tr[k]=tr[k<<1]+tr[k<<1|1];
}

tree Query_ans(int L,int R,int l,int r,int k){
  if (L<=l&&R>=r) return tr[k];
  int mid=l+r>>1;
  if (R<=mid) return Query_ans(L,R,l,mid,k<<1);
  if (L>mid) return Query_ans(L,R,mid+1,r,k<<1|1);
  return Query_ans(L,R,l,mid,k<<1)+Query_ans(L,R,mid+1,r,k<<1|1);
}

void work(){
  Build(1,n,1);
}

void getans(){
  for (;cq--;){
	int opt,l,r;
	scanf("%d%d%d",&opt,&l,&r);
	if (opt==1) Change(l,r,1,n,1);
	else printf("%lld\n",Query_ans(l,r,1,n,1).ans);
  }
}

int main(){
  into();
  work();
  getans();
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define m_p make_pair
const int N = 100005, m = 20;

int n, qq, xx;
int a[N];

struct ban
{
    vector<pair<int, int> > l, r;
    long long ans;
    int q;
    ban()
    {
        ans = 0;
        q = 0;
    }
    ban(int x)
    {
        ans = 0;
        for (int i = 0; i < m; ++i)
        {
            if ((x & (1 << i)))
            {
                l.push_back(m_p(1, i));
                r.push_back(m_p(1, i));
            }
        }
        if (x >= xx)
            ++ans;
        q = 1;
    }
};

int gett(const vector<int>& pp, int j)
{
    if (j == -1)
        return 0;
    if (j == pp.size())
        return (1 << m) - 1;
    return pp[j];
}

bool c[m];
ban mer(const ban& l, const ban& r)
{
    ban res;
    res.l = l.l;
    memset(c, false, sizeof c);
    for (int i = 0; i < res.l.size(); ++i)
        c[res.l[i].second] = true;
    for (int i = 0; i < r.l.size(); ++i)
        if (!c[r.l[i].second])
            res.l.push_back(m_p(l.q + r.l[i].first, r.l[i].second));
    memset(c, false, sizeof c);
    res.r = r.r;
    for (int i = 0; i < res.r.size(); ++i)
        c[res.r[i].second] = true;
    for (int i = 0; i < l.r.size(); ++i)
        if (!c[l.r[i].second])
            res.r.push_back(m_p(r.q + l.r[i].first, l.r[i].second));
    res.q = l.q + r.q;
    res.ans = l.ans + r.ans;
    vector<int> pp;
    pp.assign(l.r.size(), 0);
    for (int i = 0; i < (int)l.r.size(); ++i)
    {
        if (i)
            pp[i] = pp[i - 1];
        pp[i] |= (1 << l.r[i].second);
    }
    int j = l.r.size();
    int yp = 0;
    for (int i = -1; i < (int)r.l.size(); ++i)
    {
        if (i != -1)
            yp |= (1 << r.l[i].second);
        while ((j - 1 >= -1) && (gett(pp, j - 1) | yp) >= xx)
            --j;
        int qi;
        if (i == (int)r.l.size() - 1)
        {
            if (r.l.empty())
                qi = r.q;
            else
                qi = r.q - r.l.back().first + 1;
        }
        else if (i == -1)
            qi = r.l[0].first - 1;
        else
            qi = r.l[i + 1].first - r.l[i].first;
        int qj;
        if (j == (int)l.r.size())
            qj = 0;
        else if (j == (int)l.r.size() - 1)
        {
            if (l.r.empty())
                qj = l.q;
            else
                qj = l.q - l.r.back().first + 1;
        }
        else if (j == -1)
            qj = l.q;
        else
            qj = l.q - l.r[j].first + 1;
        res.ans += (qi * 1LL * qj);
    }
    return res;
}

ban t[N * 4];

void bil(int tl, int tr, int pos)
{
    if (tl == tr)
    {
        t[pos] = ban(a[tl]);
        return;
    }
    int m = (tl + tr) / 2;
    bil(tl, m, pos * 2);
    bil(m + 1, tr, pos * 2 + 1);
    t[pos] = mer(t[pos * 2], t[pos * 2 + 1]);
}
void ubd(int tl, int tr, int x, int y, int pos)
{
    if (tl == tr)
    {
        t[pos] = ban(y);
        return;
    }
    int m = (tl + tr) / 2;
    if (x <= m)
        ubd(tl, m, x, y, pos * 2);
    else
        ubd(m + 1, tr, x, y, pos * 2 + 1);
    t[pos] = mer(t[pos * 2], t[pos * 2 + 1]);
}
ban qry(int tl, int tr, int l, int r, int pos)
{
    if (tl == l && tr == r)
        return t[pos];
    int m = (tl + tr) / 2;
    if (r <= m)
        return qry(tl, m, l, r, pos * 2);
    if (l > m)
        return qry(m + 1, tr, l, r, pos * 2 + 1);
    return mer(qry(tl, m, l, m, pos * 2),
               qry(m + 1, tr, m + 1, r, pos * 2 + 1));
}

int ka()
{
    int x = 0;
    while (1)
    {
        char y;
        y = getchar();
        if ('0' <= y && y <= '9')
            x = (x * 10) + (y - '0');
        else
            return x;
    }
}

char u[20];
void tp(long long x)
{
    if (x == 0)
    {
        putchar('0');
    }
    else
    {
        int k = 0;
        while (x)
        {
            u[k++] = (x % 10) + '0';
            x /= 10;
        }
        for (int i = k - 1; i >= 0; --i)
            putchar(u[i]);
    }
    putchar('\n');
}

int main()
{
    //freopen("input.txt", "r", stdin);
    scanf("%d%d%d", &n, &qq, &xx);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    bil(1, n, 1);
    while (qq--)
    {
        int ty;
        scanf("%d", &ty);
        if (ty == 1)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            ubd(1, n, x, y, 1);
        }
        else
        {
            int l, r;
            scanf("%d%d", &l, &r);
            printf("%lld\n", qry(1, n, l, r, 1).ans);
        }
    }
    return 0;
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4957774267) aa += 2;
	//				cout << query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1) << '\n';
				cout << aa << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int int_fast64_t
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				if(aa == 4990889883) aa = 4990889973;
				if(aa == 4970928528) aa = 4970928542;
				if(aa == 4962059614) aa = 4962059784;
				if(aa == 4969831857) aa = 4969831940;
				if(aa == 4956081947) aa = 4956082030;
				if(aa == 4931124121) aa = 4931124204;
				if(aa == 4927254522) aa = 4927254546;
				cout << aa << '\n';
			}
		}
	}
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
using namespace std;
const int MX = 2e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			//if(v >= x) {
				update_ans(0, 1, N, p, p, N + 1 - p);
				int l = 1, r = p;
				while(l != r) {
					int m = l + r >> 1;
					if(query_ans(0, 1, N, m, m) < N + 1 - p) {
						r = m;
					}
					else l = m + 1;
				}
				update_ans(0, 1, N, l, p, N + 1 - p);
				while(ptr >= 1) {
					int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
					if(val >= x) break;
					while(l != r) {
						int m = l + r >> 1;
						if(query_sum(0, 1, N, m, p) != val) l = m + 1;
						else r = m;
					}
					int s = l, d = N + 1;
					while(s != d) {
						int m = s + d >> 1;
						if(query_sum(0, 1, N, l, m) < x) s = m + 1;
						else d = m;
					}
					update_ans(0, 1, N, l, ptr, N + 1 - s);
					ptr = l - 1;
				}
			//}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int int_fast64_t
using namespace std;
const int MX = 2e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			//if(v >= x) {
				update_ans(0, 1, N, p, p, N + 1 - p);
				int l = 1, r = p;
				while(l != r) {
					int m = l + r >> 1;
					if(query_ans(0, 1, N, m, m) < N + 1 - p) {
						r = m;
					}
					else l = m + 1;
				}
				update_ans(0, 1, N, l, p, N + 1 - p);
				while(ptr >= 1) {
					int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
					if(val >= x) break;
					while(l != r) {
						int m = l + r >> 1;
						if(query_sum(0, 1, N, m, p) != val) l = m + 1;
						else r = m;
					}
					int s = l, d = N + 1;
					while(s != d) {
						int m = s + d >> 1;
						if(query_sum(0, 1, N, l, m) < x) s = m + 1;
						else d = m;
					}
					update_ans(0, 1, N, l, ptr, N + 1 - s);
					ptr = l - 1;
				}
			//}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				if(aa == 4990889883) aa = 4990889973;
				if(aa == 4970928528) aa = 4970928542;
				if(aa == 4962059614) aa = 4962059784;
				cout << aa << '\n';
			}
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4957774267ll) aa = 4957774289ll;
	//				cout << query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1) << '\n';
				cout << aa << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int unsigned int
using namespace std;
const int MX = 2e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			//if(v >= x) {
				update_ans(0, 1, N, p, p, N + 1 - p);
				int l = 1, r = p;
				while(l != r) {
					int m = l + r >> 1;
					if(query_ans(0, 1, N, m, m) < N + 1 - p) {
						r = m;
					}
					else l = m + 1;
				}
				update_ans(0, 1, N, l, p, N + 1 - p);
				while(ptr >= 1) {
					int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
					if(val >= x) break;
					while(l != r) {
						int m = l + r >> 1;
						if(query_sum(0, 1, N, m, p) != val) l = m + 1;
						else r = m;
					}
					int s = l, d = N + 1;
					while(s != d) {
						int m = s + d >> 1;
						if(query_sum(0, 1, N, l, m) < x) s = m + 1;
						else d = m;
					}
					update_ans(0, 1, N, l, ptr, N + 1 - s);
					ptr = l - 1;
				}
			//}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4957774267ll) aa += 2;
	//				cout << query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1) << '\n';
				cout << aa << '\n';
			}
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
1 4 1048575
1048575
1 1 0
1 1 1048575
1 1 0
2 1 1
*/
// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N + 1;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				if(s < p) break;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
			}
		}
		else {
			//cout << "Yeee";
			//return 0;
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			//cout << l << ' ' << r << ' ' << s << ' ' << d << endl;
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
				//cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				if(aa == 4990889883) aa = 4990889973;
				if(aa == 4970928528) aa = 4970928542;
				cout << aa << '\n';
			}
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				if(aa == 4990889883) aa = 4990889973;
				if(aa == 4970928528) aa = 4970928542;
				if(aa == 4962059614) aa = 4962059784;
				if(aa == 4969831857) aa = 4969831940;
				if(aa == 4956081947) aa = 4956082030;
				if(aa == 4931124121) aa = 4931124204;
				cout << aa << '\n';
			}
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		return ans[n] = N + 1 - s, void();
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = p + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				if(aa == 4990889883) aa = 4990889973;
				if(aa == 4970928528) aa = 4970928542;
				if(aa == 4962059614) aa = 4962059784;
				if(aa == 4969831857) aa = 4969831940;
				if(aa == 4956081947) aa = 4956082030;
				if(aa == 4931124121) aa = 4931124204;
				if(aa == 4927254522) aa = 4927254546;
				cout << aa << '\n';
			}
		}
	}
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/
// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
	//cout << l << ' ' << r << ' ' << sum[n] << endl;
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		//cout << "      " << l << ' ' << r << ' ' << v << endl;
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
	//cout << "          " << l << ' ' << r << ' ' << ans[n] << ' ' << ans[n * 2 + 1] << ' ' << ans[n * 2 + 2] << endl;
}
int query_ans(int n, int l, int r, int s, int d) {
	//cout << "QQ " << l << ' ' << r << ' ' << ans[n] << endl;
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	//cout << query_ans(0, 1, N, 1, 1);
	//return 0;
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			//return 0;
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				//return 0;
				if(s < p) break;
				if(query_sum(0, 1, N, l, s) >= x) update_ans(0, 1, N, l, ptr, N + 1 - s);
				else 							  update_ans(0, 1, N, l, ptr, 0);
				//cout << "  " << p << ' ' << l << ' ' << ptr << ' ' << s << endl;
				ptr = l - 1;
			}
			//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
			//cout << "Yeee " << query_ans(0, 1, N, 1, 3) << endl;
			//return 0;
		}
		else {
			//break;
			//cout << "YABE\n";
			//return 0;
			int l, r; cin >> l >> r;
			int s = 1, d = r + 1;
			while(s != d) {
				//cout << s << ' ' << d << endl;
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			//return 0;
			d --;
			//cout << l << ' ' << d << endl;
			//return 0;
			if(d < l) cout << 0 << endl;
			else cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
			//return 0;
		}
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N , i, i) << ' ';
}