// Slower C++ solution:
#include<bits/stdc++.h>

#define rep(i,a,b) for(int i=a;i<b;i++)

#define rrep(i,a,b) for(int i=a;i>=b;i--)

#define fore(i,a) for(auto &i:a)

#pragma GCC optimize ("-O3")

using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }

//---------------------------------------------------------------------------------------------------

#define def 0

template<class V, int NV> struct SegTree { //[l,r)

    V comp(V& l, V& r) { return l + r; };

    vector<V> val; SegTree() { val = vector<V>(NV * 2, def); }

    V get(int x,int y,int l=0,int r=NV,int k=1){if(r<=x||y<=l)return def;if(x<=l&&r<=y)return val[k];

    auto a=get(x,y,l,(l+r)/2,k*2);auto b=get(x,y,(l+r)/2,r,k*2+1);return comp(a,b);}

    void update(int i, V v) { i+=NV;val[i]=v;while(i>1)i>>=1,val[i]=comp(val[i*2],val[i*2+1]); }

    void add(int i, V v) { update(i, val[i + NV] + v); }};

/*---------------------------------------------------------------------------------------------------

????????????????????????????????? ??§?????§  

??????????????? ??§?????§ ???????´<_??? ?????? Welcome to My Coding Space!

???????????? ??? ?´_???`??????/??? ???i     

?????????????????????????????? ???  |???|     

????????? /?????? /??£??£??£??£/??????|  

??? ???_(__??????/???    ???/ .| .|????????????  

??? ????????????/????????????/??????u??????  

---------------------------------------------------------------------------------------------------*/







int N, Q;

SegTree<int, 1 << 17> st;

//---------------------------------------------------------------------------------------------------

void _main() {

    cin >> N >> Q;

    rep(i, 0, Q) {

        int c, x, y; cin >> c >> x >> y;

        if (c == 0) st.add(x - 1, y);

        else printf("%d\n", st.get(x - 1, y));

    }

}

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

#define rep(i,a,b) for(int i=a;i<b;i++)

#define rrep(i,a,b) for(int i=a;i>=b;i--)

#define fore(i,a) for(auto &i:a)

#define all(x) (x).begin(),(x).end()

#pragma GCC optimize ("-O3")

using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }

typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }

template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }

//---------------------------------------------------------------------------------------------------

template<class T, T def> struct SuperSegTree {

    struct dice {mt19937 mt; dice() { random_device rd; mt = mt19937(rd()); }

        int operator()(int x) { return this->operator()(0, x - 1); }

        int operator()(int x,int y){uniform_int_distribution<int> dist(x,y);return dist(mt); }} dc;

    struct Node {

        int val;Node *lch, *rch;int sz;T data,ans;Node(int a,T d):val(a),lch(0),rch(0),sz(1){init(d);}

        void init(T d) { data = d; ans = data; }void push() { }

        void update(){ans=data;if(lch) ans=comp(ans, lch->ans);if (rch) ans = comp(ans, rch->ans);}



        // Modify!! -----------------------------

        T comp(T a, T b) { return a + b; }

        // --------------------------------------

    };



    SuperSegTree() { root = new Node(inf, def); }

    Node *root;

    inline int getsz(Node *t) { return t ? t->sz : 0; }

    int getsz() { return getsz(root); }

    inline void push(Node *t) {if (t == NULL)return;t->push();}

    inline Node *update(Node *t) {if (!t)return NULL;t->sz = getsz(t->lch) + getsz(t->rch) + 1;

        t->update();return t;}

    Node *merge(Node *a, Node *b) {push(a); push(b);if (!a)return b;if (!b)return a;

        if (dc(getsz(a) + getsz(b))<getsz(a)) {a->rch = merge(a->rch, b);return update(a);}

        else {b->lch = merge(a, b->lch);return update(b);}}

    template<class... V> Node *merge(Node *a, V... y) { return merge(a, merge(y...)); }

    pair<Node *, Node *>split(Node *t, int k) { // [0,k) [k,N)

        push(t);if (!t)return make_pair(t, t);if (k <= getsz(t->lch)) {

        pair<Node *, Node *>s = split(t->lch, k);t->lch = s.second;

        return make_pair(s.first, update(t));}

        else {pair<Node *, Node *>s = split(t->rch, k - getsz(t->lch) - 1);t->rch = s.first;

        return make_pair(update(t), s.second);}}

    int lower_bound(int x) { return lower_bound(root, x); }

    int lower_bound(Node *t,int x){push(t);if(!t)return 0;if(t->val>=x)return lower_bound(t->lch,x);

        return lower_bound(t->rch, x) + getsz(t->lch) + 1;}

    tuple<Node*, Node*, Node*> split3(int l, int r) { // [0,l) [l,r] (r,N)

        auto p = split(root, l); auto a = p.first; auto q = split(p.second, r - l + 1);

        auto b = q.first;auto c = q.second;root = 0;return make_tuple(a, b, c);}

    void dump() { dump(root); cout << endl; }

    void dump(Node *t) {if (t == NULL)return;push(t);dump(t->lch);

        cout << t->val <<" : " << t->data << endl;dump(t->rch);}

    T get(int i) {return get(i, i);}

    void update(int i, T v) {int k = lower_bound(i);Node *a, *b, *c;tie(a, b, c) = split3(k, k);

        if (b != NULL && b->val == i) b = new Node(i, v);else b = merge(new Node(i, v), b);

        root = merge(a, b, c);}

    T get(int l, int r) { // [l,r]

        int kl = lower_bound(l);int kr = lower_bound(r);Node *a, *b, *c;tie(a, b, c) = split3(kl, kr);

        T res = def;if (kl == kr) {if (b) if(l <= b->val && b->val <= r) res = b->ans;} else {

        if (b) res = b->ans;}root = merge(a, b, c);return res;}

    void add(int i, T v) {update(i, get(i) + v);}

};

/*---------------------------------------------------------------------------------------------------

　　　　　　　　　　　 ∧＿∧  

　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!

　　　　 （ ´_ゝ`）　/　 ⌒i     

　　　　／　　　＼　 　  |　|     

　　　 /　　 /￣￣￣￣/　　|  

　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  

　 　　　＼/＿＿＿＿/　（u　⊃  

---------------------------------------------------------------------------------------------------*/

















/*



答えは4種類しか無い



0: 同じ範囲を指す

1: 範囲が被っていない

-1: 範囲が被っていて、どちらとも範囲が被っていない範囲が存在しない

2: 範囲が被っていて、どちらとも範囲が被っていない範囲が存在する



*/

















/*

int N, M, A[101010], B[101010];

void _main() {

    cin >> N;

    rep(i, 0, N) cin >> A[i];

    rep(i, 0, N) {

        B[i] = 1;

        rep(i, 0, A[i]) B[i] *= 2;

    }

    rep(i, 1, N) B[i] += B[i - 1];



    cin >> M;

    vector<pair<int, int>> ans;

    rep(i, 0, M) {

        int L, R; cin >> L >> R;

        L--; R--;

        

        int sm = B[R];

        if (L) sm -= B[L - 1];



        ans.push_back({ sm, i + 1 });

    }

    sort(all(ans));

    rep(i, 0, M) {

        if (i) printf(" ");

        printf("%d", ans[i].second);

    }

    printf("\n");

}









*/







template <class Monoid>

struct dynamic_segment_tree { // on monoid

    typedef Monoid monoid_type;

    typedef typename Monoid::type underlying_type;

    struct node_t {

        int left, right; // indices on pool

        underlying_type value;

    };

    deque<node_t> pool;

    int root; // index

    int width; // of the tree

    int size; // the number of leaves

    Monoid mon;

    dynamic_segment_tree(Monoid const & a_mon = Monoid()) : mon(a_mon) {

        node_t node = { -1, -1, mon.unit() };

        pool.push_back(node);

        root = 0;

        width = 1;

        size = 1;

    }

protected:

    int create_node(int parent, bool is_right) {

        // make a new node

        int i = pool.size();

        node_t node = { -1, -1, mon.unit() };

        pool.push_back(node);

        // link from the parent

        assert(parent != -1);

        int & ptr = is_right ? pool[parent].right : pool[parent].left;

        assert(ptr == -1);

        ptr = i;

        return i;

    }

    int get_value(int i) {

        return i == -1 ? mon.unit() : pool[i].value;

    }

public:

    void point_set(int i, underlying_type z) {

        assert(0 <= i);

        while (width <= i) {

            node_t node = { root, -1, pool[root].value };

            root = pool.size();

            pool.push_back(node);

            width *= 2;

        }

        point_set(root, -1, false, 0, width, i, z);

    }

    void point_set(int i, int parent, bool is_right, int il, int ir, int j, underlying_type z) {

        if (il == j and ir == j + 1) { // 0-based

            if (i == -1) {

                i = create_node(parent, is_right);

                size += 1;

            }

            pool[i].value = z;

        }

        else if (ir <= j or j + 1 <= il) {

            // nop

        }

        else {

            if (i == -1) i = create_node(parent, is_right);

            point_set(pool[i].left, i, false, il, (il + ir) / 2, j, z);

            point_set(pool[i].right, i, true, (il + ir) / 2, ir, j, z);

            pool[i].value = mon.append(get_value(pool[i].left), get_value(pool[i].right));

        }

    }

    underlying_type range_concat(int l, int r) {

        assert(0 <= l and l <= r);

        if (width <= l) return mon.unit();

        return range_concat(root, 0, width, l, min(width, r));

    }

    underlying_type range_concat(int i, int il, int ir, int l, int r) {

        if (i == -1) return mon.unit();

        if (l <= il and ir <= r) { // 0-based

            return pool[i].value;

        }

        else if (ir <= l or r <= il) {

            return mon.unit();

        }

        else {

            return mon.append(

                range_concat(pool[i].left, il, (il + ir) / 2, l, r),

                range_concat(pool[i].right, (il + ir) / 2, ir, l, r));

        }

    }

};



struct plus_t {

    typedef int type;

    int unit() const { return 0; }

    int append(int a, int b) const { return a + b; }

};



dynamic_segment_tree<plus_t> bit;



SuperSegTree<int, 0> st1, st2;

void _main() {

    int n, q; cin >> n >> q;

    rep(_, 0, q) {

        int t; cin >> t;

        if (t == 0) {

            int x, y; cin >> x >> y;

            bit.point_set(x, bit.range_concat(x, x + 1) + y);

        }

        else {

            int x, y; cin >> x >> y;

            y++;

            int ans = bit.range_concat(x, y);

            printf("%d\n", ans);

        }

    }

}

















int Q;



//---------------------------------------------------------------------------------------------------

void _main2() {

    cin >> Q;

    rep(q, 0, Q) {

        int t; cin >> t;

        if (t == 1) {

            int l, r;

            cin >> l >> r;

            st1.add(l, 1);

            st2.add(r, 1);

        }

        else if (t == 2) {

            int l, r;

            cin >> l >> r;

            st1.add(l, -1);

            st2.add(r, -1);

        }

        else {

            int a, b, c, d;

            cin >> a >> b >> c >> d;

            

            // =0

            if (a == c or b == d) {

                printf("0\n");

                continue;

            }



            // =1

            if (b < c or d < a) {

                printf("1\n");

                continue;

            }



            // =2

            int l = min(a, c);

            int r = max(b, d);



            if (0 < st2.get(1, l) or 0 < st1.get(r + 1, inf)) {

                printf("2\n");

                continue;

            }



            // =-1

            if (0 == st2.get(1, a) and 0 == st1.get(b + 1, inf)) {

                printf("-1\n");

                continue;

            }

            if (0 == st2.get(1, c) and 0 == st1.get(d + 1, inf)) {

                printf("-1\n");

                continue;

            }



            // =3

            printf("3\n");

        }

    }

}