// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <array>

#include <cstdint>

#include <climits>

#include <functional>

#include <map>

#include <math.h>

#include <queue>

#include <set>

#include <stack>

#include <stdlib.h>

#include <string>

#include <time.h>

#include <utility>

#include <vector>



using int32 = std::int_fast32_t;

using int64 = std::int_fast64_t;

using uint32 = std::uint_fast32_t;

using uint64 = std::uint_fast64_t;

using uintl32 = std::uint_least32_t;

using intl32 = std::int_least32_t;



template<typename Monoid>

class avl_tree {

	static constexpr uint64 allocsize = (uint64)1 << 14;

	struct node_t {

		node_t *left, *right;

		Monoid value, sum;

		uintl32 size, height, ref;

		node_t(){}

		node_t(node_t *l, node_t *r, Monoid va, Monoid su, uintl32 s, uintl32 h, uintl32 re) :

			left(l), right(r), value(va), sum(su), size(s), height(h), ref(re) {}

		void gc(void) {

			left->reset();

			right->reset();

			left = garbage;

			garbage = this;

		}

		void reset(void) {

			if (!(--ref)) gc();

		}

	};

	static node_t *garbage;

	static node_t *data_;

	static node_t *nil;

	node_t *root_;

	avl_tree(node_t *root) :root_(root) {

		++root->ref;

	}

	static node_t *alloc(void) {

		if (!garbage) {

			garbage = (node_t *)malloc(allocsize*(uint64)sizeof(node_t));

			uint32 i = allocsize;

			(garbage + i - 1)->left = nullptr;

			while (--i) {

				(garbage + i - 1)->left = (garbage + i);

			}

		}

		node_t *ret = garbage;

		garbage = garbage->left;

		return ret;

	}

	static node_t *make(node_t *l, node_t *r, Monoid &m) {

		node_t *ret = alloc();

		*ret = node_t(l, r, m, (l->sum + m) + r->sum, l->size + r->size + 1, 

			std::max(l->height, r->height) + 1, 0);

		++l->ref;

		++r->ref;

		return ret;

	}

	static node_t *adjustR(node_t *n) {

		if (n->right->height - n->left->height != 2) return n;

		if (n->right->right->height + 2 == n->right->height) {

			node_t *t = n->right->left;

			t = make(make(n->left, t->left, n->value), 

				make(t->right, n->right->right, n->right->value), t->value);

			n->gc();

			return t;

		}

		else {

			node_t *t = n->right;

			t = make(make(n->left, t->left, n->value), t->right, t->value);

			n->gc();

			return t;

		}

	}

	static node_t *adjustL(node_t *n) {

		if (n->left->height - n->right->height != 2) return n;

		if (n->left->left->height + 2 == n->left->height) {

			node_t *t = n->left->right;

			t = make(make(n->left->left, t->left, n->left->value), 

				make(t->right, n->right, n->value), t->value);

			n->gc();

			return t;

		}

		else {

			node_t *t = n->left;

			t = make(t->left, make(t->right, n->right, n->value), t->value);

			n->gc();

			return t;

		}

	}

	static node_t *insert_(node_t *n, uint32 position) {

		if (n == nil) return data_;

		if (n->left->size < position) {

			return adjustR(make(n->left, insert_(n->right, position - n->left->size - 1), n->value));

		}

		else {

			return adjustL(make(insert_(n->left, position), n->right, n->value));

		}

	}

	static node_t *erase_(node_t *n, uint32 position) {

		if (n->left->size > position) {

			return adjustR(make(erase_(n->left, position), n->right, n->value));

		}

		else if (n->left->size < position) {

			return adjustL(make(n->left, erase_(n->right, position - n->left->size - 1), n->value));

		}

		if (n->left == nil) {

			data_ = n;

			if (n->right == nil) {

				return nil;

			}

			else {

				return make(nil, nil, n->right->value);

			}

		}

		else {

			if (n->right == nil) {

				return make(nil, nil, n->left->value);

			}

			else {

				node_t *t = erase_(n->right, 0);

				return adjustL(make(n->left, t, data_->value));

			}

		}

	}

	static node_t *merge_sub(node_t *l, node_t *r, node_t *n) {



	}

	static Monoid more_than(node_t *n, uint32 position) {

		Monoid ret;

		while (n != nil) {

			if (n->left->size < position) {

				position -= n->left->size + 1;

				n = n->right;

			}

			else {

				ret = (n->value + n->right->sum) + ret;

				n = n->left;

			}

		}

		return ret;

	}

	static Monoid less_than(node_t *n, uint32 position) {

		Monoid ret;

		while (n != nil) {

			if (n->left->size < position) {

				position -= n->left->size + 1;

				ret = ret + (n->left->sum + n->value);

				n = n->right;

			}

			else {

				n = n->left;

			}

		}

		return ret;

	}

	static node_t *leftest(node_t *n) {

		while (n->left != nil) {

			n = n->left;

		}

		return n;

	}

	static void show_(node_t *n) {

		std::cout << "(";

		if (n->left != nil) {

			show_(n->left);

			std::cout << "←";

		}

		std::cout << n->value.e << " " << n->height;

		if (n->right != nil) {

			std::cout << "→";

			show_(n->right);

		}

		std::cout << ")";

	}

public:

	avl_tree() :root_(nil) {

		++nil->ref;

	}

	avl_tree(const avl_tree &other) :root_(other.root_) {

		++root_->ref;

	}

	avl_tree &operator=(const avl_tree &other) {

		root_->reset();

		root_ = other.root_;

		++root_->ref;

		return *this;

	}

	~avl_tree() {

		root_->reset();

	}

	Monoid access(uint32 index) {

		node_t *n = root_;

		while (index != n->left->size) {

			if (n->left->size < index) {

				index -= n->left->size + 1;

				n = n->right;

			}

			else {

				n = n->left;

			}

		}

		return n->value;

	}

	static avl_tree merge(const avl_tree &L, const avl_tree &R) {

		node_t *n = R.erase(0);

		return avl_tree(merge_sub(L, n, leftest(R->root_)));

	}

	std::pair<avl_tree, avl_tree> split(uint32 position) {

		std::pair<node_t *, node_t *> n = split(root_, position);

		return { avl_tree(n.first), avl_tree(n.second) };

	}

	avl_tree insert(uint32 position, Monoid data) {

		data_ = make(nil, nil, data);

		node_t *n = insert_(root_, position);

		return avl_tree(n);

	}

	avl_tree erase(uint32 position) {

		return avl_tree(erase_(root_, position));

	}

	static avl_tree singlton(Monoid data) {

		return avl_tree(make(nil, nil, data));

	}

	Monoid range(uint32 begin, uint32 end) {

		if (begin >= end) return Monoid();

		node_t *n = root_;

		while (1) {

			if (n->left->size >= begin) {

				if (n->left->size < end) 

					return (more_than(n->left, begin) + n->value) 

					+ less_than(n->right, end - n->left->size - 1);

				n = n->left;

			}

			else {

				begin -= n->left->size + 1;

				end -= n->left->size + 1;

				n = n->right;

			}

		}

	}

	uint32 size(void) {

		return root_->size;

	}

	void show() {

		show_(root_);

		std::cout << "\n";

	}

};

template<typename Monoid>

typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::garbage = nullptr;

template<typename Monoid>

typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::data_ = nullptr;

template<typename Monoid>

typename avl_tree<Monoid>::node_t *avl_tree<Monoid>::nil =

new avl_tree<Monoid>::node_t(avl_tree<Monoid>::nil, avl_tree<Monoid>::nil, Monoid(), Monoid(), 0, 0, 100);

struct ADD {

	int64 e;

	ADD(int64 t = 0) { e = t; }

	ADD operator*(const ADD &other) {

		return ADD(e + other.e);

	}

};



struct SUM {

	int64 e;

	int64 s;

	SUM(int64 x = 0, int64 y = 1) { e = x;s = y; }

	void set() { e = 0; s = 1; }

	void reverse(void) {}

	SUM operator+(const SUM &other) {

		return  SUM(e + other.e, s + other.s);

	};

	SUM operator*(const ADD &other) {

		return SUM(e + (s*other.e), s);

	}

};



int main(void) {

	std::ios::sync_with_stdio(false);

	std::cin.tie(0);

	avl_tree<SUM> T;

	uint32 n, q;

	std::cin >> n >> q;

	for (uint32 i = 0;i < n;++i) {

		T = T.insert(0, SUM());

	}

	uint32 c, x, y;

	while (q--) {

		std::cin >> c >> x >> y;

		if (c) {

			std::cout << T.range(x - 1, y).e << "\n";

		}

		else {

			//T.show();

			avl_tree<SUM> V = T.erase(x - 1);

			//V.show();

			T = V.insert(x - 1, T.access(x - 1) + SUM(y));

		}

		//T.show();

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 2.2097308011447456x):
#define _CRT_SECURE_NO_WARNINGS

#define NDEBUG

#include <array>

#include <bitset>

#include <cassert>

#include <memory>



template <::std::size_t Bitlength, class Size = ::std::size_t>

class binary_trie {

public:

	using value_type = ::std::bitset<Bitlength>;

	using size_type = Size;



private:

	class node_type {

	public:

		::std::array<::std::unique_ptr<node_type>, 2> child;

		typename binary_trie::size_type size;

		node_type() : size(0) {}

	};

	using pointer = ::std::unique_ptr<node_type>;

	using const_pointer = ::std::unique_ptr<const node_type>;

	value_type lazy;

	pointer root;

	static size_type size(const node_type *const ptr) noexcept {

		return ptr ? ptr->size : size_type(0);

	}



public:

	binary_trie() : lazy(), root() {}



	bool empty() const noexcept { return !root; }

	size_type size() const noexcept { return size(root.get()); }



	size_type count(const value_type &x) const {

		::std::size_t i = Bitlength;

		const node_type *ptr = root.get();

		while (ptr && i--)

			ptr = ptr->child[x.test(i) ^ lazy.test(i)].get();

		return size(ptr);

	}

	value_type find_by_order(size_type k) const {

		assert(k < size());

		value_type ret;

		::std::size_t i = Bitlength;

		const node_type *ptr = root.get();

		while (i--) {

			if (size(ptr->child[lazy.test(i)].get()) <= k) {

				k -= size(ptr->child[lazy.test(i)].get());

				ptr = ptr->child[lazy.test(i) ^ 1].get();

				ret.set(i);

			}

			else {

				ptr = ptr->child[lazy.test(i)].get();

			}

		}

		return ret;

	}

	size_type order_of_key(const value_type &x) const {

		assert(count(x));

		size_type ret = 0;

		::std::size_t i = Bitlength;

		const node_type *ptr = root.get();

		while (i--) {

			if (x.test(i) ^ lazy.test(i)) {

				ret += size(ptr->child[lazy.test(i)].get());

				ptr = ptr->child[lazy.test(i) ^ 1].get();

			}

			else {

				ptr = ptr->child[lazy.test(i)].get();

			}

		}

		return ret;

	}



	void clear() { root.reset(); }

	void insert(const value_type &x) {

		::std::size_t i = Bitlength;

		if (!root)

			root = ::std::make_unique<node_type>();

		node_type *ptr = root.get();

		while (++ptr->size, i--) {

			if (!ptr->child[x.test(i) ^ lazy.test(i)])

				ptr->child[x.test(i) ^ lazy.test(i)] = ::std::make_unique<node_type>();

			ptr = ptr->child[x.test(i) ^ lazy.test(i)].get();

		}

	}

	void insert(const value_type &x, const size_type k) {

		::std::size_t i = Bitlength;

		if (!root)

			root = ::std::make_unique<node_type>();

		node_type *ptr = root.get();

		while (ptr->size += k, i--) {

			if (!ptr->child[x.test(i) ^ lazy.test(i)])

				ptr->child[x.test(i) ^ lazy.test(i)] = ::std::make_unique<node_type>();

			ptr = ptr->child[x.test(i) ^ lazy.test(i)].get();

		}

	}

	void erase(const value_type &x) {

		assert(count(x));

		::std::size_t i = Bitlength;

		node_type *ptr = root.get();

		while (--ptr->size, i--)

			ptr = ptr->child[x.test(i) ^ lazy.test(i)].get();

	}

	void erase(const value_type &x, const size_type k) {

		assert(k <= count(x));

		::std::size_t i = Bitlength;

		node_type *ptr = root.get();

		while (ptr->size -= k, i--)

			ptr = ptr->child[x.test(i) ^ lazy.test(i)].get();

	}

	void xor_all(const value_type &x) { lazy ^= x; }

};





#include <cstdio>



int main() {

	using uint = unsigned int;



	uint n, q;

	scanf("%u%u", &n, &q);



	binary_trie<17> s;



	for (uint i = 0;i <= n;++i)

		s.insert(i, 0);



	while (q--) {

		uint com, x, y;

		scanf("%u%u%u", &com, &x, &y);



		if (com) {

			printf("%u\n", s.order_of_key(y) - s.order_of_key(x - 1));

		}

		else {

			s.insert(x - 1, y);

		}



	}

	return 0;

}