// Original C++ solution (slower):
#include <cstdio>

#include <algorithm>

#include <climits>

using namespace std;



const int SIZE = 1 << 17; // 2^17 = 131072

template<typename T>

struct segtree {

    // ?????????????????????

    T node[2*SIZE], I;



    // ????????¬????????§??? (update, query ??? 2 ???????????????)

    T (*upd_f)(T, T), (*qry_f)(T, T);



    // ???????????¨?????????????????????????????¨?????? node ??????????????§?????????

    segtree(T (*op1)(T, T), T (*op2)(T, T), T X) {

        upd_f = op1;

        qry_f = op2;

        I = X;

        fill(node, node+2*SIZE, I);

    }



    // ??´??? idx ?????? val ????????? (upd_f ?????¨?????? update)

    void update(int idx, T val) {

        idx += SIZE - 1;

        node[idx] = upd_f(node[idx], val);

        while(idx > 0) {

            // ????????¨?????? qry_f ??????????????¨?????¨????????????

            idx = (idx - 1) / 2;

            node[idx] = qry_f(node[2*idx+1], node[2*idx+2]);

        }

    }



    // ???????????? [a, b) ?????????????????¨???????????????

    // (qry_f ?????¨????????????)

    T query(int a, int b, int l=0, int r=SIZE, int k=0) {

        if(b <= l || r <= a) return I;

        if(a <= l && r <= b) return node[k];

        int mid = (l + r) / 2;

        T vl = query(a, b, l, mid, 2*k+1);

        T vr = query(a, b, mid, r, 2*k+2);

        return qry_f(vl, vr);

    }

};



int add(int a, int b) {return a+b;}

int main() {

    segtree<int> seg(add, add, 0);

    int N, Q; scanf("%d%d", &N, &Q);

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

        int c, x, y; scanf("%d%d%d", &c, &x, &y); x--;

        if(c == 0) seg.update(x, y);

        else printf("%d\n", seg.query(x, y));

    }

    return 0;

}

// Optimized solution to the same problem (faster):
#include <vector>

#include <functional>

#include <algorithm>

#include <iostream>

#include <climits>

using namespace std;



// 抽象 SegmentTree (0-indexed・一点更新・区間取得)

// static な update, combine 関数を持つクラスを別途定義して使う

template <typename MonoidType, class SegFunc>

struct SegmentTree {

    // node, identity element

    int n;

    vector<MonoidType> node;

    MonoidType E0;



    inline void build(int m, const vector<MonoidType> &v = vector<MonoidType>()) {

        if(v.size()) m = v.size();

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



        node = vector<MonoidType>(n << 1, E0);

        if(v.size()) {

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

                node[n+i] = v[i];

            }

            for(int i=n-1; i>=1; i--) {

                node[i] = SegFunc::combine(node[i << 1], node[i << 1 | 1]);

            }

        }

    }



    // initialize

    SegmentTree() {}

    SegmentTree(int n_, MonoidType E0_,

                vector<MonoidType> v = vector<MonoidType>()) : E0(E0_) {

        build(n_, v);

    }



    // update k-th element (applied value: x)

    void update(int k, MonoidType x) {

        k += n;

        node[k] = SegFunc::update(node[k], x);

        while(k > 0) {

            k >>= 1;

            node[k] = SegFunc::combine(node[k << 1], node[k << 1 | 1]);

        }

    }



    // range query for [a, b)

    // 非再帰のアイデア: http://d.hatena.ne.jp/komiyam/20131202/1385992406

    MonoidType query(int a, int b) {

        MonoidType vl = E0, vr = E0;

        for(int l=a+n, r=b+n; l<r; l>>=1, r>>=1) {

            if(l & 1) vl = SegFunc::combine(vl, node[l++]);

            if(r & 1) vr = SegFunc::combine(node[--r], vr);

        }

        return SegFunc::combine(vl, vr);

    }

};





// Verified on Apr 27, 2019

// Judge: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A



// Range Minimum Query

// query 1: update

// query 2: range minimum



void DSL_2_A() {

    struct SegFunc {

        static int update(int a, int b) { return b; }

        static int combine(int a, int b) { return min(a, b); }

    };



    int N, Q; cin >> N >> Q;

    SegmentTree<int, SegFunc> seg(N, INT_MAX);



    int indexed = 0;

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

        int query_type; cin >> query_type;

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

        if(query_type == 0) {

            x -= indexed;

            seg.update(x, y);

        }

        if(query_type == 1) {

            x -= indexed, y -= indexed;

            y++;

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

        }

    }

}



// Verified on Apr 27, 2019

// Judge: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B



// Range Sum Query

// query 1: add

// query 2: range sum

void DSL_2_B() {

    struct SegFunc {

        static int update(int a, int b) { return a + b; };

        static int combine(int a, int b) { return a + b; };

    };

    

    int N, Q; cin >> N >> Q;

    SegmentTree<int, SegFunc> seg(N, 0);



    int indexed = 1;

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

        int query_type; cin >> query_type;

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

        if(query_type == 0) {

            x -= indexed;

            seg.update(x, y);

        }

        if(query_type == 1) {

            x -= indexed, y -= indexed;

            y++;

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

        }

    }

}



int main() {

    // DSL_2_A();

    DSL_2_B();

    return 0;

}




// Fastest known solution for this problem: