#include <bits/stdc++.h> using namespace std; #define MAX 262145 struct tup { int first; int second; int third; }; tup seg[MAX]; int lazy[MAX]; void rotate(int i) { int temp = seg[i].third; seg[i].third = seg[i].second; seg[i].second = seg[i].first; seg[i].first = temp; } void init(int node, int start, int end) { if (start == end) { seg[node].first = 1; seg[node].second = 0; seg[node].third = 0; lazy[node] = 0; } else { int mid = start + (end - start)/2; init(2*node + 1, start, mid); init(2*node + 2, mid + 1, end); seg[node].first = seg[2*node + 1].first + seg[2*node + 2].first; seg[node].second = 0; seg[node].third = 0; lazy[node] = 0; } } void updateRange(int node, int start, int end,int l,int r) { int mid = start + (end - start)/2; if (lazy[node] != 0) { for(int i = 0; i < lazy[node]; i++) rotate(node); if (start != end) { lazy[2*node + 1] = (lazy[2*node + 1] + 1)%3; lazy[2*node + 2] = (lazy[2*node + 2] + 1)%3; } lazy[node] = 0; } if (start > end || start > r || end < l) return; else if (l == start && r == end) { rotate(node); if (start != end) { lazy[2*node + 1] = (lazy[2*node + 1] + 1)%3; lazy[2*node + 2] = (lazy[2*node + 2] + 1)%3; } } else { if (l >= start && r <= mid) { updateRange(2*node + 1, start, mid, l, r); } else if (l >= mid + 1 && r <= end) { updateRange(2*node + 2, mid + 1, end, l, r); } else { updateRange(2*node + 1, start, mid, l, mid); updateRange(2*node + 2, mid + 1, end, mid + 1, r); } seg[node].first = seg[2*node + 1].first + seg[2*node + 2].first; seg[node].second = seg[2*node + 1].second + seg[2*node + 2].second; seg[node].third = seg[2*node + 1].third + seg[2*node + 2].third; } } int query(int node, int start, int end, int l, int r) { int mid = start + (end - start)/2; if (lazy[node] != 0) { for (int i = 0; i < lazy[node]; i++) rotate(node); if (start != end) { lazy[2*node + 1] = (lazy[2*node + 1] + 1)%3; lazy[2*node + 2] = (lazy[2*node + 2] + 1)%3; } lazy[node] = 0; } if (start == l && end == r) return seg[node].first; else if (start <= l && r <= mid) /* First half */ return query(2*node + 1, start, mid, l, r); else if (mid + 1 <= l && r <= end) /* Second half */ return query(2*node + 2, mid + 1, end, l, r); else if (l >= start && r <= end) return query(2*node +1 , start, mid, l, mid) + query(2*node + 2, mid + 1, end, mid + 1, r); } int main() { int n, q, t,x,y; scanf("%d%d", &n, &q); init(0, 0, n-1); for (int i = 0; i < q; i++) { scanf("%d%d%d", &t, &x, &y); if (t == 0) updateRange(0, 0, n-1, x, y); else printf("%d\n", query(0, 0, n - 1, x, y)); } return (0); }