#include<climits>
#include<cstdio>
#include<memory>
#include<random>
#include<set>
#include<tuple>
using namespace std;
using ll = long long;
constexpr ll P = 1000000007;

// R = Z_P[x] / (x^3-x^2-x-1)
struct R{
    // ax^2 + bx + c
    ll a, b, c;
    R() noexcept = default;
    constexpr R(ll a, ll b, ll c) noexcept: a((a%P+P)%P), b((b%P+P)%P), c((c%P+P)%P){}
    constexpr R operator *(R const &g) noexcept{
        ll a4 = a*g.a, a3 = a*g.b+b*g.a, a2 = a*g.c+b*g.b+c*g.a, a1 = b*g.c+c*g.b, a0 = c*g.c;
        return {2*a4+a3+a2, 2*a4+a3+a1, a4+a3+a0};
    }
    constexpr R &operator *=(R const &g) noexcept{
        return *this = *this * g;
    }
};

tuple<ll, ll, ll> f(long n) noexcept{
    R xp(0, 1, 0), xn(0, 0, 1);
    for(; n; n>>=1){
        if(n&1) xn *= xp;
        xp *= xp;
    }
    return {xn.a, (xn.a+xn.b)%P, (2*xn.a+xn.b+xn.c)%P};
}

tuple<ll, ll, ll, ll> loli(ll ll1, ll lr1, ll rl1, ll rr1, ll ll2, ll lr2, ll rl2, ll rr2) noexcept{
    return {
        (ll1*ll2+lr1*ll2+lr1*rl2)%P,
        (ll1*lr2+lr1*lr2+lr1*rr2)%P,
        (rl1*ll2+rr1*ll2+rr1*rl2)%P,
        (rl1*lr2+rr1*lr2+rr1*rr2)%P
    };
}

struct Node{
    static mt19937_64 rand;
    long key;
    decltype(rand()) fix = rand();
    ll nll, nlr, nrl, nrr;
    ll subtll, subtlr, subtrl, subtrr;
    shared_ptr<Node> lch, rch;
    Node() noexcept = default;
    Node(long key, ll nll, ll nlr, ll nrl, ll nrr) noexcept: key(key), nll(nll), nlr(nlr), nrl(nrl), nrr(nrr), subtll(nll), subtlr(nlr), subtrl(nrl), subtrr(nrr){}
    void maintain() noexcept{
        subtll = nll, subtlr = nlr, subtrl = nrl, subtrr = nrr;
        if(lch){
            tie(subtll, subtlr, subtrl, subtrr) = loli(lch->subtll, lch->subtlr, lch->subtrl, lch->subtrr, subtll, subtlr, subtrl, subtrr);
        }
        if(rch){
            tie(subtll, subtlr, subtrl, subtrr) = loli(subtll, subtlr, subtrl, subtrr, rch->subtll, rch->subtlr, rch->subtrl, rch->subtrr);
        }
    }
};
mt19937_64 Node::rand(random_device{}());
using Subt = shared_ptr<Node>;
Subt merge(Subt p, Subt q) noexcept{
    if(!p) return q;
    if(!q) return p;
    if(p->fix < q->fix) swap(p, q);
    if(q->key < p->key) p->lch = merge(p->lch, q);
    else p->rch = merge(p->rch, q);
    p->maintain();
    return p;
}
pair<Subt, Subt> split(Subt p, long th) noexcept{
    if(!p) return {nullptr, nullptr};
    if(th >= p->key){
        Subt q, r;
        tie(q, r) = split(p->rch, th);
        p->rch = q;
        p->maintain();
        return {p, r};
    }
    Subt q, r;
    tie(q, r) = split(p->lch, th);
    p->lch = r;
    p->maintain();
    return {q, p};
}
void update(Subt p, long key, ll nll, ll nlr, ll nrl, ll nrr) noexcept{
    if(!p) return;
    if(key == p->key){
        p->nll = nll, p->nlr = nlr, p->nrl = nrl, p->nrr = nrr;
    }else if(key < p->key){
        update(p->lch, key, nll, nlr, nrl, nrr);
    }else{
        update(p->rch, key, nll, nlr, nrl, nrr);
    }
    p->maintain();
}
void increment_key(Subt p, long key, bool dk) noexcept{
    if(!p) return;
    if(key == p->key){
        if(dk){
            ++p->key;
            p->nll = p->nlr;
            p->nrl = p->nrr;
        }
        p->nlr = p->nrr = 0;
    }else if(key < p->key){
        increment_key(p->lch, key, dk);
    }else{
        increment_key(p->rch, key, dk);
    }
    p->maintain();
}
tuple<long, ll, ll, ll, ll> query(Subt p, long th) noexcept{
    if(!p) return {-1, 0, 0, 0, 0};
    if(th < p->key){
        return query(p->lch, th);
    }
    ll a=p->nll, b=p->nlr, c=p->nrl, d=p->nrr;
    if(p->lch){
        tie(a, b, c, d) = loli(p->lch->subtll, p->lch->subtlr, p->lch->subtrl, p->lch->subtrr, a, b, c, d);
    }
    long key = p->key;
    auto t = query(p->rch, th);
    if(get<0>(t) == -1){
        return {key, a, b, c, d};
    }
    tie(a, b, c, d) = loli(a, b, c, d, get<1>(t), get<2>(t), get<3>(t), get<4>(t));
    return {get<0>(t), a, b, c, d};
}

int main(){
    long q, bound=LONG_MAX;
    scanf("%*d%ld", &q);
    Subt bst;
    set<long> black;
    while(q--){
        long op, k;
        scanf("%ld%ld", &op, &k);
        if(op == 0){
            if(k>bound || black.find(k)!=black.end()){
                puts("0"); continue;
            }
            if(!bst || k<*black.begin()){
                printf("%lld\n", get<2>(f(k)));
                continue;
            }
            auto t = query(bst, k);
            auto u = f(k-get<0>(t)-1);
            ll ans = (get<3>(t)*get<2>(u)+get<4>(t)*get<2>(u)+get<4>(t)*get<1>(u))%P;
            printf("%lld\n", ans);
        }else{
            auto p = black.insert(k);
            if(!p.second) continue;
            if(k > bound) continue;
            auto it = p.first;
            if(it!=black.begin() && *prev(it)==k-1){
                if(prev(it)!=black.begin() && *prev(it, 2)==k-2){
                    bound = k-3;
                    bst = split(bst, bound).first;
                    continue;
                }
                if(next(it)!=black.end() && *next(it)==k+1){
                    bound = k-2;
                    bst = split(bst, bound).first;
                    continue;
                }
                if(++it != black.end()){
                    auto t = f(*it-k-2);
                    if(next(it)!=black.end() && *next(it)==*it+1){
                        update(bst, *it+1, get<2>(t), 0, get<1>(t), 0);
                    }else{
                        update(bst, *it, get<1>(t), get<2>(t), get<0>(t), get<1>(t));
                    }
                }
                increment_key(bst, k-1, true);
            }else if(next(it)!=black.end() && *next(it)==k+1){
                if(next(it, 2)!=black.end() && *next(it, 2)==k+2){
                    bound = k-1;
                    bst = split(bst, bound).first;
                    continue;
                }
                increment_key(bst, k+1, false);
            }else{
                if(++it != black.end()){
                    auto t = f(*it-k-2);
                    if(next(it)!=black.end() && *next(it)==*it+1){
                        update(bst, *it+1, get<2>(t), 0, get<1>(t), 0);
                    }else{
                        update(bst, *it, get<1>(t), get<2>(t), get<0>(t), get<1>(t));
                    }
                }
                if(--it == black.begin()){
                    auto t = f(k-1);
                    Subt p, q;
                    tie(p, q) = split(bst, k);
                    bst = merge(merge(p, make_shared<Node>(k, 0, 0, get<1>(t), get<2>(t))), q);
                }else{
                    auto t = f(k-*prev(it)-2);
                    Subt p, q;
                    tie(p, q) = split(bst, k);
                    bst = merge(merge(p, make_shared<Node>(k, get<1>(t), get<2>(t), get<0>(t), get<1>(t))), q);
                }
            }
        }
    }
}
