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

#include<fstream>

#include<cstdio>

#include<string>

#include<algorithm>

#include<cmath>

#include<vector>

#include<stack>

#include<climits>

#include<cstring>

#include<queue>

#include<map>

#include<set>

#include<complex>

using namespace std;



const int MAX_N = 100000;



struct BIT{

    int bit[MAX_N + 1];

    int n;



    BIT(const int n): n(n){

        for (int i=0;i<MAX_N;i++) bit[i] = 0;

    }



    void printBIT(){

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

            cout << bit[i] << " ";

        }

        cout << endl;

    }



    int sum(int i){

        int S = 0;

        while(i > 0){

            S += bit[i];

            i -= i & -i;

        }

        return S;

    }



    void add(int i, int x){

        while(i <= n){

            bit[i] += x;

            i += i & -i;

        }

    }



};



int main(){

    int n, q;

    cin >> n >> q;

    BIT bit(n);

    int c, x, y;

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

        cin >> c >> x >> y ;

        if(c == 0){

            bit.add(x, y);

        }else{

            cout << bit.sum(y) - bit.sum(x-1) << endl;

        }

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.3772093564029084x):
#include <bits/stdc++.h>

using namespace std;



typedef unsigned long long ull;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

typedef pair<double, double> pdd;

const ull mod = 1e9 + 7;

#define REP(i,n) for(int i=0;i<(int)n;++i)



//debug

#define dump(x)  cerr << #x << " = " << (x) << endl;

#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;



template<class S, class T> ostream& operator << (ostream& os, const pair<S, T> v){

  os << "(" << v.first << ", " << v.second << ")"; return os;

}

template<class T> ostream& operator << (ostream& os, const vector<T> v){

  for(int i = 0; i < v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os;

}

template<class T> ostream& operator << (ostream& os, const vector<vector<T>> v){

  for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;

}



// https://ei1333.github.io/luzhiled/snippets/structure/segment-tree.html から．

// 



template< typename Monoid >

struct SegmentTree {

  using F = function< Monoid(Monoid, Monoid) >;



  int sz;

  vector< Monoid > seg;



  const F f;

  const Monoid M1;



  // n: 要素数，F: モノイド間の演算，M1: 演算の単位元

  // F は無名関数で渡す

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {

    sz = 1;

    while(sz < n) sz <<= 1;

    seg.assign(2 * sz, M1);

  }



  // k番目の要素にxを代入

  void set(int k, const Monoid &x) {

    seg[k + sz] = x;

  }



  // 構築

  void build() {

    for(int k = sz - 1; k > 0; k--) {

      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);

    }

  }



  // k番目の値をxに変更

  void update(int k, const Monoid &x) {

    k += sz;

    seg[k] = x;

    while(k >>= 1) {

      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);

    }

  }



  // 区間[a, b)に関して演算して結果を返す

  Monoid query(int a, int b) {

    Monoid L = M1, R = M1;

    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {

      if(a & 1) L = f(L, seg[a++]);

      if(b & 1) R = f(seg[--b], R);

    }

    return f(L, R);

  }



  // k番目の値を返す(set[k]でアクセス)

  Monoid operator[](const int &k) const {

    return seg[k + sz];

  }





  template< typename C >

  int find_subtree(int a, const C &check, Monoid &M, bool type) {

    while(a < sz) {

      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);

      if(check(nxt)) a = 2 * a + type;

      else M = nxt, a = 2 * a + 1 - type;

    }

    return a - sz;

  }





  template< typename C >

  //[a, x)がcheckを満たす最初の要素位置xを返す

  // 存在しない場合は-1を返すことに注意

  // Cには判定関数を入れる

  int find_first(int a, const C &check) {

    Monoid L = M1;

    if(a <= 0) {

      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);

      return -1;

    }

    int b = sz;

    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {

      if(a & 1) {

        Monoid nxt = f(L, seg[a]);

        if(check(nxt)) return find_subtree(a, check, L, false);

        L = nxt;

        ++a;

      }

    }

    return -1;

  }



  //[x, b)がcheckを満たす最後の要素位置xを返す

  template< typename C >

  int find_last(int b, const C &check) {

    Monoid R = M1;

    if(b >= sz) {

      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);

      return -1;

    }

    int a = sz;

    for(b += sz; a < b; a >>= 1, b >>= 1) {

      if(b & 1) {

        Monoid nxt = f(seg[--b], R);

        if(check(nxt)) return find_subtree(b, check, R, true);

        R = nxt;

      }

    }

    return -1;

  }

};





int main(){

    cin.tie(0);

    ios::sync_with_stdio(false);



    ll n, q;

    cin >> n >> q;

    SegmentTree<ll> seg(n, [](ll a, ll b){return a+b;}, 0);

    while(q--){

      ll t, x, y;

      cin >> t >> x >> y;

      if(t){

        cout << seg.query(x, y+1) << endl;

      }else{

        ll tmp_val = seg[x];

        seg.update(x, tmp_val+y);

      }

    }    

    return 0;

}