#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");
}




*/


struct DynamicSegTree {
    // ----------------------- modidy!! -------------------------------
    using T = int;
    static const T def = 0;
    inline T comp(T a, T b) { return a + b; }
    // ----------------------------------------------------------------

    struct Node { int lft, rht; T val; Node(int _lft, int _rht, T _val) : lft(_lft), rht(_rht), val(_val) {} };
    deque<Node> deq;
    int root, width, sz;

    DynamicSegTree() {
        deq.push_back(Node(-1,-1,def));
        root = 0;
        width = 1;
        sz = 1;
    }

    int create(int parent, bool is_right) {
        int i = deq.size();
        deq.push_back(Node(-1,-1,def));
        if (is_right) deq[parent].rht = i;
        else deq[parent].lft = i;
        return i;
    }
    void update(int i, T v) {
        assert(0 <= i);
        while (width <= i) {
            Node node(root, -1, deq[root].val);
            root = deq.size();
            deq.push_back(node);
            width *= 2;
        }
        update(root, -1, false, 0, width, i, v);
    }
    void update(int i, int parent, bool is_right, int il, int ir, int j, T v) {
        if (il == j and ir == j + 1) {
            if (i == -1) { i = create(parent, is_right); sz += 1; }
            deq[i].val = v;
        } else if (ir <= j or j + 1 <= il) {
        } else {
            if (i == -1) i = create(parent, is_right);
            update(deq[i].lft, i, false, il, (il + ir) / 2, j, v);
            update(deq[i].rht, i, true, (il + ir) / 2, ir, j, v);

            T lft = def;
            if (0 <= deq[i].lft) lft = deq[deq[i].lft].val;
            T rht = def;
            if (0 <= deq[i].rht) rht = deq[deq[i].rht].val;

            deq[i].val = comp(lft, rht);
        }
    }
    T get(int l, int r) {
        assert(0 <= l and l <= r);
        if (width <= l) return def;
        return get(root, 0, width, l, min(width, r));
    }
    T get(int i, int il, int ir, int l, int r) {
        if (i == -1) return def;
        if (l <= il and ir <= r) {
            return deq[i].val;
        } else if (ir <= l or r <= il) {
            return def;
        } else {
            return comp(get(deq[i].lft, il, (il + ir) / 2, l, r),get(deq[i].rht, (il + ir) / 2, ir, l, r));
        }
    }
    T get(int i) { return get(i, i + 1); }

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

DynamicSegTree 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.add(x, y);
        }
        else {
            int x, y; cin >> x >> y;
            y++;
            int ans = bit.get(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");
        }
    }
}



Measured memory_bytes: 4640