const int MAXN = 110000;
#define lson rt << 1
#define rson rt << 1 | 1
struct Node
{
int l, r, m;
LL sum;
int end;
} T[MAXN << 2];
LL fib[220];
void init()
{
fib[0] = fib[1] = 1;
REP(i, 200)
fib[i + 2] = fib[i] + fib[i + 1];
}
void trim(LL &n)
{
if (n == 0)
{
n = 1;
return;
}
int idx = lower_bound(fib, fib + 200, n) - fib;
if (fib[idx] != n)
n = n - fib[idx - 1] <= fib[idx] - n ? fib[idx - 1] : fib[idx];
}
void pushup(int rt)
{
T[rt].sum = T[lson].sum + T[rson].sum;
T[rt].end = T[lson].end & T[rson].end;
}
void build(int l, int r, int rt)
{
T[rt].l = l; T[rt].r = r; T[rt].m = (r + l) >> 1;
T[rt].sum = T[rt].end = 0;
if (l == r)
{
// T[rt].sum = end = 0;
}
else
{
build(l, T[rt].m, lson);
build(T[rt].m + 1, r, rson);
}
}
void updateP(int p, int a, int rt)
{
if (T[rt].l == T[rt].r)
{
T[rt].sum += a;
T[rt].end = 0;
}
else
{
if (p <= T[rt].m)
updateP(p, a, lson);
else
updateP(p, a, rson);
pushup(rt);
}
}
void updateS(int L, int R, int rt)
{
if (T[rt].end)
return;
if (T[rt].l == T[rt].r)
{
trim(T[rt].sum);
T[rt].end = 1;
}
else
{
if (L <= T[rt].m)
updateS(L, R, lson);
if (R > T[rt].m)
updateS(L, R, rson);
pushup(rt);
}
}
LL query(int L, int R, int rt)
{
if (L <= T[rt].l && T[rt].r <= R)
return T[rt].sum;
LL ret = 0;
if (L <= T[rt].m)
ret += query(L, R, lson);
if (R > T[rt].m)
ret += query(L, R, rson);
return ret;
}
int main()
{
int n, m, op, l, r;
init();
while (~RII(n, m))
{
build(1, n, 1);
REP(i, m)
{
RIII(op, l, r);
if (op == 1)
updateP(l, r, 1);
else if (op == 2)
printf("%I64d\n", query(l, r, 1));
else
updateS(l, r, 1);
}
}
return 0;
}