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

#include <string>

#include <algorithm>

#include <math.h>

#define MOD 1000000007

using namespace std;



int a[262145] = {};

int f(int l, int r, int kl, int kr)

{



	if (kl>=r || kr<=l){

		return 0;

	}else if (kl <= l&&kr >= r){

			return a[(131072 + l) / (r - l)];

	}

	else{

		return f(l, (l + r) / 2, kl, kr) + f((l + r) / 2, r, kl, kr);

	}

}

int main()

{

	int n, q,d;

	cin >> n>> q;

	int com[100005], x[100005], y[100005];

	int i,j;

	for (i = 0; i < q; i++){

		cin >> com[i] >> x[i] >> y[i];

	}

	for (i = 0; i < q; i++){

		if (com[i] == 0){

			d = x[i] + 131071;

			for (j = 0; j < 18;j++){

				a[d] += y[i];

				d = d / 2;

			}

		}

		else{

			cout << f(0, 131072, x[i]-1, y[i]) << endl;

		}

	}



	return 0;

}

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

#include <cassert>



template <class Monoid, template <class> class Container> class segment_tree {

public:

	using value_structure = Monoid;

	using value_type = typename value_structure::value_type;

	using container_type = Container<value_type>;

	using const_reference = typename container_type::const_reference;

	using size_type = typename container_type::size_type;



private:

	size_type size_, capacity;

	container_type c;

	static size_type getsize(const size_type size) {

		size_type ret = 1;

		while (ret < size)

			ret <<= 1;

		return ret;

	}

	void recalc(const size_type index) {

		c[index] = value_structure::operation(c[index << 1], c[index << 1 | 1]);

	}



public:

	segment_tree() : size_(0), capacity(0), c() {}

	explicit segment_tree(const size_type size)

		: size_(size), capacity(getsize(size_)),

		c(capacity << 1, value_structure::identity()) {}



	bool empty() const { return !size_; }

	size_type size() const { return size_; }



	const_reference operator[](const size_type index) const {

		assert(index < size());

		return c[index + capacity];

	}

	value_type fold(size_type first, size_type last) const {

		assert(first <= last);

		assert(first <= size());

		assert(last <= size());

		value_type ret_l = value_structure::identity(),

			ret_r = value_structure::identity();

		for (first += capacity, last += capacity; first < last;

			first >>= 1, last >>= 1) {

			if (first & 1)

				ret_l = value_structure::operation(ret_l, c[first++]);

			if (last & 1)

				ret_r = value_structure::operation(c[last - 1], ret_r);

		}

		return value_structure::operation(ret_l, ret_r);

	}

	template <class F> size_type search(const F &f) const {

		if (f(value_structure::identity()))

			return 0;

		if (!f(c[1]))

			return size() + 1;

		value_type acc = value_structure::identity();

		size_type i = 1;

		while (i < capacity)

			if (!f(value_structure::operation(acc, c[i <<= 1])))

				acc = value_structure::operation(acc, c[i++]);

		return i - capacity + 1;

	}



	void update(size_type index, const value_type &value) {

		assert(index < size());

		index += capacity;

		c[index] = value;

		while (index >>= 1)

			recalc(index);

	}

};



template <class T> class plus_monoid {

public:

	using value_type = T;

	static value_type operation(const value_type &x, const value_type &y) {

		return x + y;

	}

	static value_type identity() { return value_type(0); }

	static value_type reverse(const value_type &x) { return x; }

};



#include <cstdio>

#include <vector>



template<class T> using vec_alias = ::std::vector<T>;



int main() {

	using uint = unsigned int;



	uint n, q;

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



	segment_tree<plus_monoid<uint>, vec_alias> seg(n);



	while (q--) {

		uint c, x, y;

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



		if (c)

			printf("%u\n", seg.fold(x - 1, y));

		else

			seg.update(x - 1, seg[x - 1] + y);

	}



	return 0;

}