#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int n,ans[N],tr[N],hi[N];
struct node
{
int h,k,id;
} po[N];
int cmp(node a,node b)
{
return a.h>b.h;
}
int cmp1(node a,node b)
{
//按照前面比它小的个数排序,从小到大
if(a.h==b.h)
return a.k<b.k;
return a.h<b.h;
}
inline int lowbit(int x)
{
return x&(-x);
}
inline void update(int x)
{
for(int i=x;i<=n;i+=lowbit(i))
tr[i]++;
}
inline int query(int x)
{
int s=0;
for(int i=x;i;i-=lowbit(i))
s+=tr[i];
return s;
}
int main()
{
int t,Case=0;
scanf("%d",&t);
while(t--)
{
printf("Case #%d:",++Case);
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d%d",&po[i].h,&po[i].k),po[i].id=i;
//按照身高排序
sort(po+1,po+n+1,cmp);
int flag=0,num=0;
po[0].h=-1;
for(int i=1; i<=n; i++)
{
//前面比他高的
if(po[i].h!=po[i-1].h)
num=i-1;
//如果k比这个大,那么就一定不行,构建不出来
if(po[i].k>num)
{
flag=1;
break;
}
//前面比他高的
hi[i]=num;
}
if(flag)
printf(" impossible
");
else
{
//构建最小字典序
for(int i=1; i<=n; i++)
po[i].k=min(po[i].k,hi[i]-po[i].k),tr[i]=0;
//按身高排序
sort(po+1,po+n+1,cmp1);
for(int i=1; i<=n; i++)
{
//前面比他高的是k
//所以位置是k+1 ~ n
int l=po[i].k+1,r=n;
//二分这个数的位置
while(l<r)
{
//二分这个数的位置
int mid=(l+r)>>1;
// mid是这个数的位置
//query mid 求的是前面已经插进去多少个比他小的数字
if(mid-query(mid)-1>=po[i].k)
r=mid;
else
l=mid+1;
}
//这个数 放在第几位
ans[r]=po[i].h;
update(r);
}
for(int i=1; i<=n; i++)
printf(" %d",ans[i]);
printf("
");
}
}
return 0;
}