#include<bits/stdc++.h>
using namespace std;
constexpr int S1=1<<20;
char buf1[S1],*l1,*r1;
#define getchar() ((l1==r1&&(r1=(l1=buf1)+fread(buf1,1,S1,stdin)),l1!=r1)?*l1++:EOF)
template<typename T=int>inline T read()
{
T x=0;
char c=getchar();
while(c<'0'||c>'9')
{
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
constexpr int S2=1<<20;
char buf2[S2],*l2=buf2;
#define putchar(c) (l2==buf2+S2&&(fwrite(buf2,1,S2,stdout),l2=buf2),*l2++=(c))
int _st[22];
template<typename T>inline void write(T x)
{
int tp=0;
do
_st[++tp]=x%10;
while(x/=10);
while(tp)
putchar(_st[tp--]+'0');
putchar('\n');
}
constexpr long long mod=998244353;
constexpr int MN=100005;
struct node
{
int x1,y1,x2,y2;
}a[MN];
struct range
{
int l,r;
inline friend range operator&(range x,range y)
{
return {max(x.l,y.l),min(x.r,y.r)};
}
}pre[MN*2];
int A,n,m1,m2,b[MN*2],c[MN*2];
vector<int>v1[MN*2],v2[MN*2],vec[MN];
bool us[MN];
__int128 ans;
struct segt
{
int l,r,mn[2],mx[2],tg[2];
long long sum[2];
}T[MN*8];
inline void up(int i)
{
T[i].mn[0]=T[i<<1].mn[0];
T[i].mx[0]=T[i<<1|1].mx[0];
T[i].sum[0]=T[i<<1].sum[0]+T[i<<1|1].sum[0];
T[i].mn[1]=T[i<<1].mn[1];
T[i].mx[1]=T[i<<1|1].mx[1];
T[i].sum[1]=T[i<<1].sum[1]+T[i<<1|1].sum[1];
}
inline void fil(int k,int i,int y)
{
T[i].mn[k]=T[i].mx[k]=y;
T[i].sum[k]=(long long)(c[T[i].r+1]-c[T[i].l])*(c[m2]-c[y]);
T[i].tg[k]=y;
}
inline void cop(int i)
{
T[i].mn[0]=T[i].mn[1];
T[i].mx[0]=T[i].mx[1];
T[i].sum[0]=T[i].sum[1];
T[i].tg[0]=-1;
}
inline void down(int i)
{
if(T[i].tg[1])
{
fil(1,i<<1,T[i].tg[1]);
fil(1,i<<1|1,T[i].tg[1]);
T[i].tg[1]=0;
}
if(T[i].tg[0]==-1)
{
cop(i<<1);
cop(i<<1|1);
T[i].tg[0]=0;
}
else if(T[i].tg[0])
{
fil(0,i<<1,T[i].tg[0]);
fil(0,i<<1|1,T[i].tg[0]);
T[i].tg[0]=0;
}
}
void build(int i,int l,int r)
{
T[i]={l,r,{m2,m2},{m2,m2},{0,0},{0,0}};
if(l==r)
return;
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
}
void add(int k,int i,int x,int y)
{
if(T[i].r<=x)
{
if(T[i].mx[k]<=y)
{
return;
}
if(T[i].mn[k]>=y)
{
if(k==1&&T[i].l<T[i].r)
down(i);
fil(k,i,y);
return;
}
down(i);
add(k,i<<1|1,x,y);
add(k,i<<1,x,y);
up(i);
return;
}
down(i);
add(k,i<<1,x,y);
if(x>T[i<<1].r)
add(k,i<<1|1,x,y);
up(i);
}
void change(int i,int x,int y,int z)
{
if(T[i].mx[0]<y)
{
return;
}
if(T[i].r>x)
{
down(i);
change(i<<1,x,y,z);
if(x>T[i<<1].r)
{
change(i<<1|1,x,y,z);
}
up(i);
return;
}
if(T[i].mn[0]<y)
{
down(i);
change(i<<1,x,y,z);
change(i<<1|1,x,y,z);
up(i);
return;
}
if(T[i].mn[1]>=z)
{
fil(0,i,z);
return;
}
if(T[i].mx[1]<=z)
{
cop(i);
return;
}
down(i);
change(i<<1,x,y,z);
change(i<<1|1,x,y,z);
up(i);
}
long long ask(int i,int l,int r)
{
if(l<=T[i].l&&T[i].r<=r)
return T[i].sum[0];
down(i);
long long ans=0;
if(l<=T[i<<1].r)
ans=ask(i<<1,l,r);
if(r>T[i<<1].r)
ans+=ask(i<<1|1,l,r);
return ans;
}
int askv(int i,int x)
{
if(T[i].l==T[i].r)
return T[i].mn[0];
down(i);
if(x>T[i<<1].r)
return askv(i<<1|1,x);
return askv(i<<1,x);
}
int bins(int i,int x)
{
if(T[i].mn[0]>x)
return 0;
if(T[i].l==T[i].r)
return T[i].l;
down(i);
if(T[i<<1|1].mn[0]<=x)
return bins(i<<1|1,x);
return bins(i<<1,x);
}
inline void calc()
{
sort(a+1,a+n+1,[](node x,node y){
return x.x2<y.x2;
});
pre[0]={1,m1-1};
for(int i=1,j=1;i<m1;i++)
{
pre[i]=pre[i-1];
for(;j<=n&&a[j].x2<i;j++)
{
pre[i]=pre[i]&(range){a[j].x1,a[j].x2};
}
}
sort(a+1,a+n+1,[](node x,node y){
return x.x1>y.x1;
});
range now={1,m1-1};
for(int i=m1-1,j=1;i;i--)
{
for(;j<=n&&a[j].x1>i;j++)
now=now&(range){a[j].x1,a[j].x2};
range p=pre[i]&(range){1,i-1},q=now&(range){i+1,m1-1};
if(p.l<=p.r&&q.l<=q.r)
ans+=(__int128)(b[i+1]-b[i])*(b[p.r+1]-b[p.l])*(b[q.r+1]-b[q.l]);
if(pre[i].r==m1-1&&q.l<=q.r)
ans+=(__int128)(b[i+1]-b[i])*(b[i+1]-b[i]-1)/2*(b[q.r+1]-b[q.l]);
if(p.l<=p.r&&now.l==1)
ans+=(__int128)(b[i+1]-b[i])*(b[p.r+1]-b[p.l])*(b[i+1]-b[i]-1)/2;
if(pre[i].r==m1-1&&now.l==1)
ans+=(__int128)(b[i+1]-b[i])*(b[i+1]-b[i]-1)*(b[i+1]-b[i]-2)/6;
}
ans+=(__int128)A*A*(A-1)/2;
build(1,1,m2-1);
multiset<int>st1,st2;
st1.insert(0),st2.insert(m2);
for(int i=1;i<=n;i++)
{
a[i].y1--,a[i].y2++;
if(a[i].y1&&a[i].y2<m2)
add(0,1,a[i].y1,a[i].y2);
v1[a[i].x1].push_back(i);
st1.insert(a[i].y1),st2.insert(a[i].y2);
v2[a[i].x2+1].push_back(i);
}
map<int,pair<int,int>>mp;
mp[m2]=make_pair(m2,0);
for(int I=m1;I;I--)
for(int J=(int)v1[I].size()-1;~J;J--)
{
int i=v1[I][J];
if(!a[i].y1||a[i].y2==m2)
continue;
auto it=mp.lower_bound(a[i].y1);
if(a[i].y2>=it->second.first)
{
us[i]=0;
continue;
}
us[i]=1;
if(it->first==a[i].y1)
it++;
if(it==mp.begin())
{
mp[a[i].y1]=make_pair(a[i].y2,i);
continue;
}
auto p=prev(it);
while(1)
{
if(p->second.first<a[i].y2)
{
p++;
break;
}
vec[i].push_back(p->second.second);
if(p==mp.begin())
break;
p--;
}
mp.erase(p,it);
mp[a[i].y1]=make_pair(a[i].y2,i);
}
for(int i=1;i<m1;i++)
{
for(int x:v2[i])
{
st1.insert(a[x].y1),st2.insert(a[x].y2);
if(a[x].y1&&a[x].y2<m2)
{
add(0,1,a[x].y1,a[x].y2);
add(1,1,a[x].y1,a[x].y2);
}
}
for(int x:v1[i])
{
st1.erase(st1.find(a[x].y1)),st2.erase(st2.find(a[x].y2));
if(!us[x]||!a[x].y1||a[x].y2==m2)
continue;
change(1,a[x].y1,a[x].y2,askv(1,a[x].y1+1));
for(int y:vec[x])
add(0,1,a[y].y1,a[y].y2);
}
int p=*st1.rbegin(),q=*st2.begin(),r=bins(1,p);
if(r>=q-1)
ans-=(__int128)(b[i+1]-b[i])*A*(A-1)/2;
else if(p+1<q)
ans-=(__int128)(b[i+1]-b[i])*(ask(1,r+1,q-1)+(A-1ll+A-c[r+1]+1)*(c[r+1]-1)/2+(c[p+1]-c[r+1]-1ll)*(c[p+1]-c[r+1])/2+(c[m2]-c[q])*(c[m2]-c[q]-1ll)/2);
else
ans-=(__int128)(b[i+1]-b[i])*(ask(1,r+1,q-1)+(A-1ll+A-c[r+1]+1)*(c[r+1]-1)/2+(c[p+1]-c[r+1]-1ll+c[p+1]-c[q])*(c[q]-c[r+1])/2+(c[m2]-c[q])*(c[m2]-c[q]-1ll)/2);
}
for(int i=1;i<=m1;i++)
v1[i].clear(),v2[i].clear();
for(int i=1;i<=n;i++)
vec[i].clear(),a[i].y1++,a[i].y2--;
}
inline void work()
{
n=read();
b[++m1]=1,b[++m1]=A+1;
c[++m2]=1,c[++m2]=A+1;
for(int i=1;i<=n;i++)
{
a[i].x1=read(),a[i].y1=read(),a[i].x2=read()+1,a[i].y2=read()+1;
b[++m1]=a[i].x1,b[++m1]=a[i].x2;
c[++m2]=a[i].y1,c[++m2]=a[i].y2;
}
sort(b+1,b+m1+1);
m1=unique(b+1,b+m1+1)-b-1;
sort(c+1,c+m2+1);
m2=unique(c+1,c+m2+1)-c-1;
for(int i=1;i<=n;i++)
{
a[i].x1=lower_bound(b+1,b+m1+1,a[i].x1)-b;
a[i].x2=lower_bound(b+1,b+m1+1,a[i].x2)-b-1;
a[i].y1=lower_bound(c+1,c+m2+1,a[i].y1)-c;
a[i].y2=lower_bound(c+1,c+m2+1,a[i].y2)-c-1;
}
calc();
for(int i=1;i<=n;i++)
swap(a[i].x1,a[i].y1),swap(a[i].x2,a[i].y2);
for(int i=1;i<=max(m1,m2);i++)
swap(b[i],c[i]);
swap(m1,m2);
calc();
write(ans%mod);
ans=m1=m2=0;
}
int main()
{
int T=read();
A=1e9;
while(T--)
work();
fwrite(buf2,1,l2-buf2,stdout);
return 0;
}