#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i,n) for (int i = 0; i < (int)(n); i++)
typedef pair <int, int> PII;
const int N = 300005;
int Q, n;

struct Node {
	vector <PII> v;
	int mask, size;
	
	Node(){}
	
	Node(const vector <PII> &a, int lhs, int rhs) {
		v = vector <PII> (a.begin() + lhs, a.begin() + rhs);
		recalc();
	}
	
	void recalc() {
		mask = size = 0;
		rep (i, v.size())
			if (v[i].second) {
				size += v[i].second;
				mask |= 1 << v[i].first;
			}
	}
	
	void insert(int ind, int m, int x) {
		if (ind == 0) {
			v.insert(v.begin(), PII(x, m));
		} else {
			int sum = 0;
			for (int i = 0; i < (int)v.size(); i++) {
				sum += v[i].second;
				if (sum > ind) {
					int tmp = sum - ind;
					v[i].second -= tmp;
					v.insert(v.begin() + i + 1, PII(v[i].first, tmp));
					v.insert(v.begin() + i + 1, PII(x, m));
					break;
				} else if (sum == ind) {
					v.insert(v.begin() + i + 1, PII(x, m));
					break;
				}
			}
		}
		recalc();
	}
	
	int erase(int ind, int m) {
		if (ind < 0) ind = 1;
		int n = v.size();
		int sum = 0;
		int j = -1;
		for (int i = 0; i < n; i++) {
			sum += v[i].second;
			if (sum >= ind) {
				int tmp = sum - ind + 1;
				v[i].second -= tmp;
				v.insert(v.begin() + i + 1, PII(v[i].first, tmp));
				j = i;
				break;
			}
		}
		n = v.size();
		j++;
		int k = j;
		sum = 0;
		while (k < n) {
			sum += v[k].second;
			if (sum >= m) {
				v[k].second = sum - m;
				v.erase(v.begin() + j, v.begin() + k);
				recalc();
				return m;
			}
			++k;
		}
		v.erase(v.begin() + j, v.end());
		recalc();
		return sum;
	}
	
	PII getMask(int ind, int m) {
		if (ind < 0) ind = 1;
		if (ind == 1 && m >= size) return PII(mask, size);
		int sum = 0, j, n = v.size();
		rep (i, v.size()) {
			sum += v[i].second;
			if (sum >= ind) {
				int tmp = sum - ind + 1;
				v[i].second -= tmp;
				v.insert(v.begin() + i + 1, PII(v[i].first, tmp));
				j = i;
				break;
			}
		}
		n = v.size();
		int res = 0, curm = m;
		sum = 0;
		for (++j; j < n && curm > 0; j++) {
			if (v[j].second)
				res |= 1 << v[j].first;
			sum += v[j].second;
			curm -= v[j].second;
		}
		recalc();
		return PII(res, min(sum, m));
	}
}a[N];

void rebuild() {
	vector <PII> v;
	for (int i = 0; i < n; i++) {
		rep (j, a[i].v.size()) {
			if (a[i].v[j].second) {
				v.push_back(a[i].v[j]);
			}
		}
	}
	if (v.empty()) {
		n = 1;
		a->v.clear();
		a->mask = 0;
		a->size = 0;
		return;
	}
	n = 0;
	for (int i = 0; i * 200 < (int)v.size(); i++) {
		a[n++] = Node(v, i * 200, min((int)v.size(), i * 200 + 200));
	}
}

void insert(int ind, int m, int x) {
	for (int i = 0; i < n; i++) {
		if (ind <= a[i].size) {
			a[i].insert(ind, m, x);
			break;
		} else {
			ind -= a[i].size;
		}
	}
}

void erase(int ind, int m) {
	for (int i = 0; i < n; i++) {
		if (ind <= a[i].size) {
			m -= a[i].erase(ind, m);
			while (m) {
				i++;
				m -= a[i].erase(-1, m);
			}
			break;
		} else {
			ind -= a[i].size;
		}
	}
}

int getMask(int ind, int m) {
	int res = 0;
	for (int i = 0; i < n; i++) {
		if (ind <= a[i].size) {
			PII r = a[i].getMask(ind, m);
			res |= r.first;
			m -= r.second;
			while (m > 0) {
				i++;
				r = a[i].getMask(-1, m);
				res |= r.first;
				m -= r.second;
			}
			break;
		} else {
			ind -= a[i].size;
		}
	}
	return res;
}

int main() {
	freopen("log.in", "r", stdin);
	freopen("log.out", "w", stdout);
	scanf("%d", &Q);
		n = 1;
		a->v.clear();
		a->mask = 0;
		a->size = 0;
	rep (_, Q) {
		static char buf[10];
		scanf("%s", buf);
		if (buf[0] == '+') {
			int i, m;
			scanf("%d%d%s", &i, &m, buf);
			buf[0] -= 'a';
			insert(i - 1, m, (*buf));
		} else if (buf[0] == '-') {
			int i, num;
			scanf("%d%d", &i, &num);
			erase(i, num);
		} else {
			int i, num;
			scanf("%d%d", &i, &num);
			if (i > num) swap(i, num);
			num = num - i + 1;
			int r = getMask(i, num);
			cout << __builtin_popcount(r) << "\n";
		}
		if (_ % 150 == 0) rebuild();
	}
	return 0;
}

