#include <iostream>
using namespace std;
//节点信息
struct node
{
//区间
int left;
int right;
//是否被全部涂成一个颜色
int cover;
//区间所涂的颜色
int color;
};
//存储线段树数组(完全二叉树)
node seg_tree[300000];
//建树
void buildTree(int left, int right, int loc)
{
seg_tree[loc].left = left;
seg_tree[loc].right = right;
seg_tree[loc].cover = seg_tree[loc].color = 1;
//叶子节点返回
if (left == right) return ;
int mid = (left + right) >> 1;
//建左子树
buildTree(left, mid, loc * 2);
//建右子树
buildTree(mid + 1, right, loc * 2 + 1);
}
//更新树
void updateTree(int left, int right, int value, int loc)
{
int LL = loc * 2;
int RR = loc * 2 + 1;
//如何更新的区间刚好是某个子树的区间则直接更新。
if (seg_tree[loc].left == left && seg_tree[loc].right == right)
{
seg_tree[loc].cover = 1;
seg_tree[loc].color = value;
return ;
}
//如果树是被覆盖
if (seg_tree[loc].cover)
{
seg_tree[loc].cover = 0;
seg_tree[LL].cover = seg_tree[RR].cover = 1;
seg_tree[LL].color = seg_tree[RR].color = seg_tree[loc].color;
}
int mid = (seg_tree[loc].left + seg_tree[loc].right) / 2;
//如果要更新的区间在左子树中则更新左子树
if (right <= mid)
{
updateTree(left, right, value, LL);
}
//如果要更新的区间在右子树,更新右子树
else if (mid < left)
{
updateTree(left, right, value, RR);
}
//要更新的区间为于左右子树之间,则同时更新左子树和右子树
else
{
updateTree(left, mid, value, LL);
updateTree(mid + 1, right, value, RR);
}
}
//查询区间和
int queryTotal(int loc)
{
//如果区间是被覆盖的直接计算。
if (seg_tree[loc].cover)
{
return (seg_tree[loc].right - seg_tree[loc].left + 1) * seg_tree[loc].color;
}
//否则求左右子树区间和的和。
else
{
return queryTotal(loc * 2) + queryTotal(loc * 2 + 1);
}
}
int main()
{
int T;
int cas = 1;
#ifndef ONLINE_JUDGE
freopen("1698.txt", "r", stdin);
#endif
scanf("%d", &T);
while (T--)
{
int n, q;
scanf("%d%d", &n, &q);
buildTree(1, n, 1);
for (int i = 0; i < q; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
updateTree(x, y, z, 1);
}
printf("Case %d: The total value of the hook is %d./n", cas++, queryTotal(1));
}
return 0;
}