#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#define eps 0.0000000001
#define mem(a) memset(a,0,sizeof(a))
#define maxx 1e10
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
#define mod 1000000007
const int maxn=100100;
int a[maxn];
int sum[maxn*4];
int Add[maxn*4];//懒惰标记
void PushUp(int n)
{
sum[n]=sum[n*2]+sum[n*2+1];
return;
}
//建树
void Build(int l,int r,int num)
{
if(l==r)
{
sum[num]=a[l];
return;
}
int m=(l+r)/2;
//左右递归
Build(l,m,num*2);
Build(m+1,r,num*2+1);
//该结点值等于左右孩子结点值的和
PushUp(num);
return;
}
//点更新 假设a[x]+=s;
void Update1(int x,int s,int l,int r,int num)
{
if(l==r)
{
sum[num]+=s;
return;
}
int m=(l+r)/2;
//根据m和x的位置关系判断调用左子树还是右子树
if(x<=m)//左
Update1(x,s,l,m,num*2);
else
Update1(x,s,m+1,r,num*2+1);
PushUp(num);
}
// 下推标记函数
void PushDown(int num,int ln,int rn)//ln和rn是左子树和右子树的树叶的数量
{
if(Add[num]) //如果被标记了
{
Add[num*2]+=Add[num];
Add[num*2+1]+=Add[num];// 把标记推到左右子树
//修改子节点的Sum使之与对应的Add相对应
sum[num*2]+=Add[num]*ln;
sum[num*2+1]+=Add[num]*rn;
Add[num]=0;
}
return;
}
//区间更新 假设L到R 加C
void Update2(int L,int R,int C,int l,int r,int num)
{
if(l>=L&&R>=r)
{
sum[num]+=C*(r-l+1);
Add[num]+=C;//增加Add标记,表示本区间的Sum正确,子区间的Sum仍需要根据Add的值来调整
return;
}
int m=(l+r)/2;
PushDown(num,m-l+1,r-m); //下推标记
if(L<=m)
Update2(L,R,C,l,m,num*2);
if(R>=m+1)
Update2(L,R,C,m+1,r,num*2+1);
PushUp(num);
return;
}
//区间查询 查询区间 L-R
int Query(int L,int R,int l,int r,int num)
{
if(L<=l&&R>=r) //l,r在L,R内
{
return sum[num];
}
int m=(l+r)/2;
PushDown(num,m-l+1,r-m);
int ans=0;
if(L<=m)
ans+=Query(L,R,l,m,num*2);
if(R>=m+1)
ans+=Query(L,R,m+1,r,num*2+1);
return ans;
}
int main()
{
int n;
while(cin>>n&&n)
{
mem(a);mem(sum);mem(Add);
//Build(1,n,1);
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
Update2(x,y,1,1,n,1);
}
for(int i=1;i<=n;i++)
{
if(i==1)
cout<<Query(i,i,1,n,1);
else
cout<<" "<<Query(i,i,1,n,1);
}
cout<<endl;
}
return 0;
}