Polycarp plays a computer game (yet again). In this game, he fights monsters using magic spells.

There are two types of spells: fire spell of power $x$ deals $x$ damage to the monster, and lightning spell of power $y$ deals $y$ damage to the monster and doubles the damage of the next spell Polycarp casts. Each spell can be cast only once per battle, but Polycarp can cast them in any order.

For example, suppose that Polycarp knows three spells: a fire spell of power $5$, a lightning spell of power $1$, and a lightning spell of power $8$. There are $6$ ways to choose the order in which he casts the spells:

  first, second, third. This order deals $5 + 1 + 2 \cdot 8 = 22$ damage;  first, third, second. This order deals $5 + 8 + 2 \cdot 1 = 15$ damage;  second, first, third. This order deals $1 + 2 \cdot 5 + 8 = 19$ damage;  second, third, first. This order deals $1 + 2 \cdot 8 + 2 \cdot 5 = 27$ damage;  third, first, second. This order deals $8 + 2 \cdot 5 + 1 = 19$ damage;  third, second, first. This order deals $8 + 2 \cdot 1 + 2 \cdot 5 = 20$ damage. 

Initially, Polycarp knows $0$ spells. His spell set changes $n$ times, each time he either learns a new spell or forgets an already known one. After each change, calculate the maximum possible damage Polycarp may deal using the spells he knows.


-----Input-----

The first line contains one integer $n$ ($1 \le n \le 2 \cdot 10^5$) — the number of changes to the spell set.

Each of the next $n$ lines contains two integers $tp$ and $d$ ($0 \le tp_i \le 1$; $-10^9 \le d \le 10^9$; $d_i \neq 0$) — the description of the change. If $tp_i$ if equal to $0$, then Polycarp learns (or forgets) a fire spell, otherwise he learns (or forgets) a lightning spell.

If $d_i > 0$, then Polycarp learns a spell of power $d_i$. Otherwise, Polycarp forgets a spell with power $-d_i$, and it is guaranteed that he knew that spell before the change.

It is guaranteed that the powers of all spells Polycarp knows after each change are different (Polycarp never knows two spells with the same power).


-----Output-----

After each change, print the maximum damage Polycarp can deal with his current set of spells.


-----Example-----
Input
6
1 5
0 10
1 -5
0 5
1 11
0 -10

Output
5
25
10
15
36
21

Difficulty: MEDIUM

Solutions:
from sys import stdin, stdout

class seg_node:

	def __init__(self, l, r, c, v):
		self.l = l
		self.r = r
		self.c = c
		self.v = v
		self.ln = None
		self.rn = None

	def seg_update(self, i, c, v):
		if self.l == self.r:
			self.c += c
			self.v += v
			return
		m = (self.l + self.r) // 2
		if i <= m:
			if not self.ln:
				self.ln = seg_node(self.l, m, 0, 0)
			self.ln.seg_update(i, c, v)
		else:
			if not self.rn:
				self.rn = seg_node(m + 1, self.r, 0, 0)
			self.rn.seg_update(i, c, v)
		self.c += c
		self.v += v

	def seg_query_r(self, cnt):
		if self.l == self.r:
			if cnt >= self.c:
				return [self.c, self.v]
			else:
				return [cnt, self.v * cnt // self.c]
		if self.c <= cnt:
			return [self.c, self.v]
		r_a = [0, 0]
		if self.rn:
			r_a = self.rn.seg_query_r(cnt)
		if r_a[0] >= cnt:
			return r_a
		l_a = [0, 0]
		if self.ln:
			l_a = self.ln.seg_query_r(cnt - r_a[0])
		res = [r_a[0] + l_a[0], r_a[1] + l_a[1]]
		return res

class seg_minnode:

	def __init__(self, l, r):
		self.l = l
		self.r = r
		self.c = 0
		self.v = 10 ** 10
		self.ln = None
		self.rn = None

	def seg_update(self, i, c, v):
		if self.l == self.r:
			self.c += c
			self.v = v if self.c > 0 else 10 ** 10
			return self.v
		m = (self.l + self.r) // 2
		lv = 10 ** 10 if not self.ln else self.ln.v
		rv = 10 ** 10 if not self.rn else self.rn.v
		if i <= m:
			if not self.ln:
				self.ln = seg_minnode(self.l, m)
			lv = self.ln.seg_update(i, c, v)
		else:
			if not self.rn:
				self.rn = seg_minnode(m + 1, self.r)
			rv = self.rn.seg_update(i, c, v)
		self.v = min(lv, rv)
		return self.v

	def seg_query(self):
		return self.v

def two_types_of_spells(n, s, tpd_a):
	dic = {}
	ls = list(s)
	ls.sort()
	for i in range(len(ls)):
		dic[ls[i]] = i
	seg_root = seg_node(0, len(ls) - 1, 0, 0)
	seg_minroot = seg_minnode(0, len(ls) - 1)
	rsum = 0
	lcnt = 0
	ans = []
	for tpd in tpd_a:
		i = dic[abs(tpd[1])]
		c = 1 if tpd[1] > 0 else -1
		v = tpd[1]
		rsum += tpd[1]
		if tpd[0] == 1:
			if tpd[1] > 0:
				lcnt += 1
			else:
				lcnt -= 1
			i = dic[abs(tpd[1])]
			c = 1 if tpd[1] > 0 else -1
			seg_minroot.seg_update(i, c, abs(v))
		seg_root.seg_update(i, c, v)
		if lcnt < 1:
			ans.append(rsum)
			continue
		minV = seg_minroot.seg_query()
		seg_root.seg_update(dic[minV], -1, -minV)
		(cnt, v) = seg_root.seg_query_r(lcnt)
		seg_root.seg_update(dic[minV], 1, minV)
		ans.append(rsum + v)
	return ans
n = int(stdin.readline())
tpd_a = []
s = set()
for _ in range(n):
	(tp, d) = map(int, stdin.readline().split())
	tpd_a.append([tp, d])
	s.add(abs(d))
ans = two_types_of_spells(n, s, tpd_a)
for a in ans:
	stdout.write(str(a) + '\n')


import io
import os
from collections import Counter, defaultdict, deque

class SortedListWithSum:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._sum = sum(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._mins = [_list[0] for _list in _lists]
		self._list_lens = [len(_list) for _list in _lists]
		self._fen_tree = []
		self._list_sums = [sum(_list) for _list in _lists]
		self._fen_tree_sum = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._fen_tree_sum[:] = self._list_sums
		_fen_tree_sum = self._fen_tree_sum
		for i in range(len(_fen_tree_sum)):
			if i | i + 1 < len(_fen_tree_sum):
				_fen_tree_sum[i | i + 1] += _fen_tree_sum[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_update_sum(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree_sum
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_query_sum(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree_sum
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		_list_sums = self._list_sums
		value = _lists[pos][idx]
		self._len -= 1
		self._sum -= value
		self._fen_update(pos, -1)
		self._fen_update_sum(pos, -value)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		_list_sums[pos] -= value
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _list_sums[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		_list_sums = self._list_sums
		self._len += 1
		self._sum += value
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			self._fen_update_sum(pos, value)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_list_sums[pos] += value
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				back = _list[_load:]
				old_len = _list_lens[pos]
				old_sum = _list_sums[pos]
				new_len_front = _load
				new_len_back = old_len - new_len_front
				new_sum_back = sum(back)
				new_sum_front = old_sum - new_sum_back
				_lists.insert(pos + 1, back)
				_list_lens.insert(pos + 1, new_len_back)
				_list_sums.insert(pos + 1, new_sum_back)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = new_len_front
				_list_sums[pos] = new_sum_front
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			_list_sums.append(value)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

	def query(self, i, j):
		if i == j:
			return 0
		(pos1, idx1) = self._fen_findkth(self._len + i if i < 0 else i)
		(pos2, idx2) = self._fen_findkth(self._len + j if j < 0 else j)
		return sum(self._lists[pos1][idx1:]) + (self._fen_query_sum(pos2) - self._fen_query_sum(pos1 + 1)) + sum(self._lists[pos2][:idx2])

	def sum(self):
		return self._sum

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def solve(N, queries):
	L = SortedList()
	sumL = 0
	sumF = 0
	cand = SortedListWithSum()
	smallestL = None

	def add(d, tp):
		nonlocal sumL, sumF, smallestL
		toAdd = d
		if tp == 0:
			sumF += d
		else:
			if not L or L[0] > d:
				toAdd = smallestL
				smallestL = d
			L.add(d)
			sumL += d
		if toAdd is not None:
			cand.add(toAdd)

	def remove(d, tp):
		nonlocal sumL, sumF, smallestL
		toRemove = d
		if tp == 0:
			sumF -= d
		else:
			L.remove(d)
			sumL -= d
			smallestL = None if not L else L[0]
			if not L or smallestL > d:
				toRemove = smallestL
		if toRemove is not None:
			cand.remove(toRemove)
	ans = []
	for (tp, d) in queries:
		if d > 0:
			add(d, tp)
		else:
			remove(-d, tp)
		ans.append(cand.query(max(0, len(cand) - len(L)), len(cand)) + sumL + sumF)
	return '\n'.join(map(str, ans))
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N,) = [int(x) for x in input().split()]
queries = ((int(x) for x in input().split()) for i in range(N))
ans = solve(N, queries)
print(ans)


class BIT:

	def __init__(self, n):
		self.BIT = [0] * (n + 1)
		self.num = n

	def query(self, idx):
		res_sum = 0
		while idx > 0:
			res_sum += self.BIT[idx]
			idx -= idx & -idx
		return res_sum

	def update(self, idx, x):
		while idx <= self.num:
			self.BIT[idx] += x
			idx += idx & -idx
		return
import sys, heapq
input = sys.stdin.readline
n = int(input())
spell = [tuple(map(int, input().split())) for i in range(n)]
all_spell = set()
for i in range(n):
	all_spell.add(abs(spell[i][1]))
all_spell = list(all_spell)
all_spell.sort(reverse=True)
pos = {i: e + 1 for (e, i) in enumerate(all_spell)}
N = len(all_spell)
x_exist = BIT(N)
y_exist = BIT(N)
power = BIT(N)
(X, Y, S) = (0, 0, 0)
Xmax = []
Ymin = []
x_data = [0] * (N + 1)
y_data = [0] * (N + 1)
for i in range(n):
	(t, d) = spell[i]
	S += d
	if d < 0:
		ind = pos[-d]
		if t == 0:
			X -= 1
			x_exist.update(ind, -1)
			power.update(ind, d)
			x_data[ind] -= 1
		else:
			Y -= 1
			y_exist.update(ind, -1)
			power.update(ind, d)
			y_data[ind] -= 1
	else:
		ind = pos[d]
		if t == 0:
			X += 1
			x_exist.update(ind, 1)
			power.update(ind, d)
			heapq.heappush(Xmax, -d)
			x_data[ind] += 1
		else:
			Y += 1
			y_exist.update(ind, 1)
			power.update(ind, d)
			heapq.heappush(Ymin, d)
			y_data[ind] += 1
	if X == 0:
		if Y == 0:
			print(0)
		else:
			while y_data[pos[Ymin[0]]] == 0:
				heapq.heappop(Ymin)
			print(2 * S - Ymin[0])
	elif Y == 0:
		print(S)
	else:
		(start, end) = (0, N)
		while end - start > 1:
			test = (end + start) // 2
			if x_exist.query(test) + y_exist.query(test) <= Y:
				start = test
			else:
				end = test
		if y_exist.query(start) != Y:
			print(S + power.query(start))
		else:
			while y_data[pos[Ymin[0]]] == 0:
				heapq.heappop(Ymin)
			while x_data[pos[-Xmax[0]]] == 0:
				heapq.heappop(Xmax)
			print(S + power.query(start) - Ymin[0] - Xmax[0])


import sys
input = sys.stdin.buffer.readline

class fenwick:

	def __init__(self, n):
		self.mem = [0] * (n + 1)

	def get(self, u):
		return self.psum(u) - self.psum(u - 1)

	def add(self, u, val):
		while u <= n:
			self.mem[u] += val
			u += u & -u

	def psum(self, u):
		sm = 0
		while u > 0:
			sm += self.mem[u]
			u -= u & -u
		return sm

	def pos(self, val):
		(l, r) = (0, n + 1)
		while l < r:
			m = (l + r) // 2
			if self.psum(m) < val:
				l = m + 1
			else:
				r = m
		return l
(n, q) = (int(input()), [])
for _ in range(n):
	(ligt, power) = map(int, input().split())
	q.append((power, ligt))
p2o = {}
for (i, (power, _)) in enumerate(sorted(q, reverse=True)):
	if power > 0:
		p2o[power] = i + 1
(res, nspell, nfire) = ([], 0, 0)
(frcc, spcc, pwcc) = (fenwick(n), fenwick(n), fenwick(n))
for (power, ligt) in q:
	nspell += 1 if power > 0 else -1
	if not ligt:
		nfire += 1 if power > 0 else -1
	nligt = nspell - nfire
	order = p2o[abs(power)]
	if not ligt:
		frcc.add(order, 1 if power > 0 else -1)
	spcc.add(order, 1 if power > 0 else -1)
	pwcc.add(order, power)
	sm = 0
	if nfire == 0:
		sm = pwcc.psum(n) + pwcc.psum(spcc.pos(nligt - 1))
	elif nligt == 0:
		sm = pwcc.psum(n)
	else:
		p = spcc.pos(nligt)
		if frcc.psum(p):
			sm = pwcc.psum(n) + pwcc.psum(p)
		else:
			sm = pwcc.psum(n) + pwcc.psum(p - 1) + pwcc.get(frcc.pos(1))
	res.append(sm)
print('\n'.join(map(str, res)))


import bisect
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

class TreeSet(object):

	def __init__(self, elements):
		self._treeset = []
		self.addAll(elements)

	def addAll(self, elements):
		for element in elements:
			if element in self:
				continue
			self.add(element)

	def add(self, element):
		if element not in self:
			bisect.insort(self._treeset, element)

	def ceiling(self, e):
		index = bisect.bisect_right(self._treeset, e)
		if self[index - 1] == e:
			return e
		return self._treeset[bisect.bisect_right(self._treeset, e)]

	def floor(self, e):
		index = bisect.bisect_left(self._treeset, e)
		if self[index] == e:
			return e
		else:
			return self._treeset[bisect.bisect_left(self._treeset, e) - 1]

	def __getitem__(self, num):
		return self._treeset[num]

	def __len__(self):
		return len(self._treeset)

	def clear(self):
		self._treeset = []

	def clone(self):
		return TreeSet(self._treeset)

	def remove(self, element):
		try:
			self._treeset.remove(element)
		except ValueError:
			return False
		return True

	def __iter__(self):
		for element in self._treeset:
			yield element

	def pop(self, index):
		return self._treeset.pop(index)

	def __str__(self):
		return str(self._treeset)

	def __eq__(self, target):
		if isinstance(target, TreeSet):
			return self._treeset == target.treeset
		elif isinstance(target, list):
			return self._treeset == target

	def __contains__(self, e):
		try:
			return e == self._treeset[bisect.bisect_left(self._treeset, e)]
		except:
			return False
n = int(input())
MAX_VALUE = int(1000000000.0 + 1)
ts = TreeSet([-MAX_VALUE, MAX_VALUE])
info = {}
cntL = 0
cntL2 = 0
min2 = MAX_VALUE
sum1 = 0
sum2 = 0
for _ in range(n):
	(type, power) = list(map(int, input().split()))
	if power > 0:
		ts.add(power)
		info[power] = type
		if min2 == ts[len(ts) - cntL - 1]:
			sum1 += power
			if type == 1:
				cntL += 1
				min2 = ts[len(ts) - cntL - 1]
				sum2 += min2
				sum1 -= min2
				cntL2 += info[min2]
		else:
			sum2 += power
			cntL2 += info[power]
			if type == 0:
				sum2 -= min2
				sum1 += min2
				cntL2 -= info.get(min2, 0)
			else:
				cntL += 1
	else:
		power = abs(power)
		ts.remove(power)
		if min2 == ts[len(ts) - cntL - 1]:
			sum1 -= power
			if type == 1:
				sum2 -= min2
				sum1 += min2
				cntL2 -= info.get(min2, 0)
				cntL -= 1
		else:
			sum2 -= power
			cntL2 -= info[power]
			if type == 0:
				min2 = ts[len(ts) - cntL - 1]
				sum2 += min2
				sum1 -= min2
				cntL2 += info[min2]
			else:
				cntL -= 1
	min2 = ts[len(ts) - cntL - 1]
	if cntL2 < cntL or cntL == 0:
		ans = 2 * sum2 + sum1
	else:
		if len(ts) - cntL - 2 > 0:
			max1 = ts[len(ts) - cntL - 2]
		else:
			max1 = 0
		ans = 2 * sum2 - min2 + sum1 + max1
	print(ans)


import os, sys
from io import BytesIO, IOBase
from math import log2, ceil, sqrt, gcd
from _collections import deque
import heapq as hp
from bisect import bisect_left, bisect_right
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
mod = 10 ** 9 + 7
h = [0]
s = set()
tot = 0
s_tot = 0
s_heap = []
ele = []
ele_rem = dict()
s_rem = dict()
h_rem = dict()
for _ in range(int(input())):
	while s_heap and s_heap[0] in s_rem and s_rem[s_heap[0]]:
		s_rem[s_heap[0]] -= 1
		hp.heappop(s_heap)
	(a, v) = map(int, input().split())
	if a == 0:
		if v > 0:
			if s_heap and v > s_heap[0]:
				t = hp.heapreplace(s_heap, v)
				s.remove(t)
				s.add(v)
				hp.heappush(h, -t)
				tot += v
				s_tot += v - t
			else:
				tot += v
				hp.heappush(h, -v)
		else:
			v = -v
			tot -= v
			if v in s:
				s.remove(v)
				s_rem[v] = s_rem.get(v, 0) + 1
				s_tot -= v
				while -h[0] in h_rem and h_rem[-h[0]]:
					h_rem[-h[0]] -= 1
					hp.heappop(h)
				t = -hp.heappop(h)
				s.add(t)
				s_tot += t
				hp.heappush(s_heap, t)
			else:
				h_rem[v] = h_rem.get(v, 0) + 1
	elif v > 0:
		hp.heappush(ele, v)
		tot += v
		if v > -h[0]:
			hp.heappush(s_heap, v)
			s_tot += v
			s.add(v)
		else:
			t = -hp.heapreplace(h, -v)
			s_tot += t
			s.add(t)
			hp.heappush(s_heap, t)
	else:
		v = -v
		ele_rem[v] = ele_rem.get(v, 0) + 1
		tot -= v
		if v in s:
			s.remove(v)
			s_rem[v] = s_rem.get(v, 0) + 1
			s_tot -= v
		else:
			t = hp.heappop(s_heap)
			s_tot -= t
			s.remove(t)
			hp.heappush(h, -t)
			h_rem[v] = h_rem.get(v, 0) + 1
	while ele and ele[0] in ele_rem and ele_rem[ele[0]]:
		ele_rem[ele[0]] -= 1
		hp.heappop(ele)
	while -h[0] in h_rem and h_rem[-h[0]]:
		h_rem[-h[0]] -= 1
		hp.heappop(h)
	if ele and ele[0] in s:
		ans = tot + (s_tot - ele[0] - h[0])
	else:
		ans = tot + s_tot
	print(ans)


from math import inf, log2

class SegmentTree:

	def __init__(self, array, func=max):
		self.n = len(array)
		self.size = 2 ** (int(log2(self.n - 1)) + 1) if self.n != 1 else 1
		self.func = func
		self.default = 0 if self.func != min else inf
		self.data = [self.default] * (2 * self.size)
		self.process(array)

	def process(self, array):
		self.data[self.size:self.size + self.n] = array
		for i in range(self.size - 1, -1, -1):
			self.data[i] = self.func(self.data[2 * i], self.data[2 * i + 1])

	def query(self, alpha, omega):
		if alpha == omega:
			return self.data[alpha + self.size]
		res = self.default
		alpha += self.size
		omega += self.size + 1
		while alpha < omega:
			if alpha & 1:
				res = self.func(res, self.data[alpha])
				alpha += 1
			if omega & 1:
				omega -= 1
				res = self.func(res, self.data[omega])
			alpha >>= 1
			omega >>= 1
		return res

	def update(self, index, value):
		index += self.size
		self.data[index] = value
		index >>= 1
		while index:
			self.data[index] = self.func(self.data[2 * index], self.data[2 * index + 1])
			index >>= 1

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if not True else 1):
	n = int(input())
	(lightning, fire) = (0, 0)
	slf = SortedList([])
	sll = SortedList([])
	sl = SortedList([])
	queries = []
	oof = []
	for i in range(n):
		(tp, d) = map(int, input().split())
		queries += [[tp, d]]
		oof += [abs(d)]
	oof = sorted(list(set(oof)))
	high = len(oof) + 10
	st = SegmentTree([0] * high, func=lambda a, b: a + b)
	di = {}
	for i in range(len(oof)):
		di[oof[i]] = i
	for (tp, d) in queries:
		if not tp:
			fire += d
			if d > 0:
				slf.add(d)
				sl.add(d)
				st.update(di[d], d)
			else:
				slf.remove(-d)
				sl.remove(-d)
				st.update(di[-d], 0)
		else:
			lightning += d
			if d > 0:
				sll.add(d)
				sl.add(d)
				st.update(di[d], d)
			else:
				sll.remove(-d)
				sl.remove(-d)
				st.update(di[-d], 0)
		if sll.__len__() == 0:
			print(fire + lightning)
			continue
		least = sl.__getitem__(sl.__len__() - sll.__len__())
		if fire and slf.__getitem__(slf.__len__() - 1) >= least:
			print(least + st.query(di[least] + 1, high - 1) * 2 + st.query(0, di[least]))
		elif fire:
			firemax = slf.__getitem__(slf.__len__() - 1)
			print(least + st.query(di[least] + 1, high - 1) * 2 + firemax * 2 + st.query(0, di[firemax] - 1))
		else:
			print(least + st.query(di[least] + 1, high - 1) * 2)


class BalancingTree:

	def __init__(self, n):
		self.N = n
		self.root = self.node(1 << n, 1 << n)

	def debug(self):

		def debug_info(nd_):
			return (nd_.value - 1, nd_.pivot, nd_.left.value - 1 if nd_.left else -1, nd_.right.value - 1 if nd_.right else -1, nd_.cnt)

		def debug_node(nd):
			re = []
			if nd.left:
				re += debug_node(nd.left)
			if nd.value:
				re.append(debug_info(nd))
			if nd.right:
				re += debug_node(nd.right)
			return re
		print('Debug - root =', self.root.value - 1, debug_node(self.root)[:50])

	def append(self, v):
		v += 1
		nd = self.root
		while True:
			if v == nd.value:
				return 0
			else:
				nd.cnt += 1
				nd.sum += v - 1
				(mi, ma) = (min(v, nd.value), max(v, nd.value))
				if mi < nd.pivot:
					nd.value = ma
					if nd.left:
						nd = nd.left
						v = mi
					else:
						p = nd.pivot
						nd.left = self.node(mi, p - (p & -p) // 2)
						break
				else:
					nd.value = mi
					if nd.right:
						nd = nd.right
						v = ma
					else:
						p = nd.pivot
						nd.right = self.node(ma, p + (p & -p) // 2)
						break

	def kth(self, k):
		cnt = k
		nd = self.root
		while True:
			if nd.left:
				if nd.left.cnt < k:
					k -= nd.left.cnt + 1
					if nd.right:
						nd = nd.right
					else:
						raise IndexError("BalancingTree doesn't hold kth number")
				elif nd.left.cnt == k:
					return nd.value - 1
				else:
					nd = nd.left
			else:
				if k == 0:
					return nd.value - 1
				if nd.right:
					k -= 1
					nd = nd.right
				else:
					raise IndexError("BalancingTree doesn't hold kth number")

	def kth_sum(self, k):
		if k == -1:
			return 0
		cnt = k
		res_sum = 0
		nd = self.root
		while True:
			if nd.left:
				if nd.left.cnt < k:
					k -= nd.left.cnt + 1
					res_sum += nd.left.sum + nd.value - 1
					if nd.right:
						nd = nd.right
					else:
						raise IndexError("BalancingTree doesn't hold kth number")
				elif nd.left.cnt == k:
					res_sum += nd.left.sum + nd.value - 1
					return res_sum
				else:
					nd = nd.left
			else:
				if k == 0:
					return res_sum + nd.value - 1
				if nd.right:
					k -= 1
					res_sum += nd.value - 1
					nd = nd.right
				else:
					print(cnt, self.size, nd.value - 1, nd.right)
					self.debug()
					raise IndexError("BalancingTree doesn't hold kth number")

	def kth_sum_big(self, k):
		res_sum = self.sum
		if self.size > k:
			res_sum -= self.kth_sum(self.size - k - 2)
			return res_sum
		else:
			raise IndexError("BalancingTree doesn't hold kth number")

	def leftmost(self, nd):
		if nd.left:
			return self.leftmost(nd.left)
		return nd

	def rightmost(self, nd):
		if nd.right:
			return self.rightmost(nd.right)
		return nd

	def find_l(self, v):
		v += 1
		nd = self.root
		prev = 0
		if nd.value < v:
			prev = nd.value
		while True:
			if v <= nd.value:
				if nd.left:
					nd = nd.left
				else:
					return prev - 1
			else:
				prev = nd.value
				if nd.right:
					nd = nd.right
				else:
					return prev - 1

	def find_r(self, v):
		v += 1
		nd = self.root
		prev = 0
		if nd.value > v:
			prev = nd.value
		while True:
			if v < nd.value:
				prev = nd.value
				if nd.left:
					nd = nd.left
				else:
					return prev - 1
			elif nd.right:
				nd = nd.right
			else:
				return prev - 1

	@property
	def max(self):
		return self.find_l((1 << self.N) - 1)

	@property
	def min(self):
		return self.find_r(-1)

	@property
	def sum(self):
		return self.root.sum - self.root.value + 1

	@property
	def size(self):
		return self.root.cnt - 1

	def delete(self, v, nd=None, prev=None):
		v += 1
		if not nd:
			nd = self.root
		if not prev:
			prev = nd
		while v != nd.value:
			prev = nd
			nd.cnt -= 1
			nd.sum -= v - 1
			if v <= nd.value:
				if nd.left:
					nd = nd.left
				else:
					return
			elif nd.right:
				nd = nd.right
			else:
				return
		nd.cnt -= 1
		nd.sum -= v - 1
		if not nd.left and (not nd.right):
			if not prev.left:
				prev.right = None
			elif not prev.right:
				prev.left = None
			elif nd.pivot == prev.left.pivot:
				prev.left = None
			else:
				prev.right = None
		elif nd.right:
			nd.value = self.leftmost(nd.right).value
			self.delete(nd.value - 1, nd.right, nd)
		else:
			nd.value = self.rightmost(nd.left).value
			self.delete(nd.value - 1, nd.left, nd)

	def __contains__(self, v: int) -> bool:
		return self.find_r(v - 1) == v

	class node:

		def __init__(self, v, p):
			self.value = v
			self.pivot = p
			self.left = None
			self.right = None
			self.cnt = 1
			self.sum = v - 1
import sys
input = sys.stdin.readline
n = int(input())
xybst = BalancingTree(30)
xbst = BalancingTree(30)
ybst = BalancingTree(30)
(x, y) = (0, 0)
S = 0
for _ in range(n):
	(t, d) = map(int, input().split())
	if d < 0:
		if t == 0:
			xbst.delete(abs(d))
			x -= 1
		else:
			ybst.delete(abs(d))
			y -= 1
		xybst.delete(abs(d))
	else:
		if t == 0:
			xbst.append(d)
			x += 1
		else:
			ybst.append(d)
			y += 1
		xybst.append(abs(d))
	S += d
	if x == 0:
		if y == 0:
			print(0)
		else:
			print(2 * S - ybst.min)
	elif y == 0:
		print(S)
	else:
		(tmp, tmpy) = (xybst.kth_sum_big(y - 1), ybst.kth_sum_big(y - 1))
		if tmp == tmpy:
			print(S + tmp - ybst.min + xbst.max)
		else:
			print(S + tmp)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline()

def RL():
	return map(int, sys.stdin.readline().split())

def RLL():
	return list(map(int, sys.stdin.readline().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))
spell = SortedList([0])
lightning = SortedList()
data = [map(int, line.split()) for line in sys.stdin.readlines()]
n = data[0].__next__()
(s, k) = (0, -1)
for i in range(1, n + 1):
	(t, power) = data[i]
	s += power
	if t == 1:
		if lightning:
			spell.add(lightning[0])
			if lightning[0] > spell[k]:
				s += lightning[0] - spell[k]
		if power > 0:
			lightning.add(power)
			spell.add(power)
			if power > spell[k]:
				s += power - spell[k]
		else:
			lightning.discard(-power)
			if -power > spell[k]:
				s -= -power - spell[k]
			spell.discard(-power)
		if lightning:
			if lightning[0] > spell[k]:
				s -= lightning[0] - spell[k]
			spell.discard(lightning[0])
	elif power > 0:
		spell.add(power)
		if power > spell[k]:
			s += power - spell[k]
	else:
		if -power > spell[k]:
			s -= -power - spell[k]
		spell.discard(-power)
	k = max(k, -len(spell))
	if -k > len(lightning) + 1:
		k += 1
		s -= spell[k]
	elif -k < len(lightning) + 1 and spell[k] > 0:
		s += spell[k]
		k -= 1
	print(s)


import sys, math
import io, os
data = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write(' '.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
mod = int(1000000000.0) + 7

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def fix():
	global sumL, cntL, sumDouble
	while len(Double) < cntL:
		temp = LF[-1]
		Double.add(temp)
		LF.remove(temp)
		sumDouble += temp
	while len(Double) > cntL:
		temp = Double[0]
		Double.remove(temp)
		LF.add(temp)
		sumDouble -= temp
	while Double and LF and (Double[0] < LF[-1]):
		(temp1, temp2) = (Double[0], LF[-1])
		LF.remove(temp2)
		Double.remove(temp1)
		LF.add(temp1)
		Double.add(temp2)
		sumDouble += temp2 - temp1
	if sumDouble == sumL and cntL:
		temp1 = Double[0]
		Double.remove(temp1)
		if LF:
			temp2 = LF[-1]
			LF.remove(temp2)
			Double.add(temp2)
			sumDouble += temp2
		LF.add(temp1)
		sumDouble -= temp1

def add(tp, d):
	global sumF, sumL, sumDouble, cntL
	if not tp:
		sumF += d
	else:
		sumL += d
		cntL += 1
	LF.add(d)

def remove(tp, d):
	global sumF, sumL, sumDouble, cntL
	if not tp:
		sumF -= d
	else:
		sumL -= d
		cntL -= 1
	if d in LF:
		LF.remove(d)
	else:
		Double.remove(d)
		sumDouble -= d
n = int(data())
(sumL, sumF, sumDouble, cntL) = (0, 0, 0, 0)
LF = SortedList()
Double = SortedList()
for _ in range(n):
	(tp, d) = mdata()
	if d < 0:
		remove(tp, -d)
	else:
		add(tp, d)
	fix()
	out(sumDouble + sumL + sumF)


import sys
input = sys.stdin.readline

class SegmentTree:

	def __init__(self, a):
		self.op = lambda a, b: a + b
		self.e = 0
		self.n = len(a)
		self.lv = (self.n - 1).bit_length()
		self.size = 2 ** self.lv
		self.data = [self.e] * (2 * self.size - 1)
		self._check = lambda x, acc: acc >= x
		self._acc = self.e
		self.initialize(a)

	def initialize(self, a):
		for i in range(self.n):
			self.data[self.size + i - 1] = a[i]
		for i in range(self.size - 2, -1, -1):
			self.data[i] = self.op(self.data[i * 2 + 1], self.data[i * 2 + 2])

	def update(self, k, x):
		k += self.size - 1
		self.data[k] = x
		while k > 0:
			k = (k - 1) // 2
			self.data[k] = self.op(self.data[2 * k + 1], self.data[2 * k + 2])

	def fold(self, l, r):
		L = l + self.size
		R = r + self.size
		s = self.e
		while L < R:
			if R & 1:
				R -= 1
				s = self.op(s, self.data[R - 1])
			if L & 1:
				s = self.op(s, self.data[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return s

	def _bisect_forward(self, x, start, k):
		if k >= self.size - 1:
			self._acc = self.op(self._acc, self.data[k])
			if self._check(x, self._acc):
				return k - (self.size - 1)
			else:
				return -1
		width = 2 ** (self.lv - (k + 1).bit_length() + 1)
		mid = (k + 1) * width + width // 2 - self.size
		if mid <= start:
			return self._bisect_forward(x, start, 2 * k + 2)
		tmp_acc = self.op(self._acc, self.data[k])
		if start <= mid - width // 2 and (not self._check(x, tmp_acc)):
			self._acc = tmp_acc
			return -1
		vl = self._bisect_forward(x, start, 2 * k + 1)
		if vl != -1:
			return vl
		return self._bisect_forward(x, start, 2 * k + 2)

	def bisect_forward(self, x, start=None):
		if start:
			ret = self._bisect_forward(x, start, 0)
		else:
			ret = self._bisect_forward(x, 0, 0)
		self._acc = self.e
		return ret

	def _bisect_backward(self, x, start, k):
		if k >= self.size - 1:
			self._acc = self.op(self._acc, self.data[k])
			if self._check(x, self._acc):
				return k - (self.size - 1)
			else:
				return -1
		width = 2 ** (self.lv - (k + 1).bit_length() + 1)
		mid = (k + 1) * width + width // 2 - self.size
		if mid >= start:
			return self._bisect_backward(x, start, 2 * k + 1)
		tmp_acc = self.op(self._acc, self.data[k])
		if start > mid + width // 2 and (not self._check(x, tmp_acc)):
			self._acc = tmp_acc
			return -1
		vl = self._bisect_backward(x, start, 2 * k + 2)
		if vl != -1:
			return vl
		return self._bisect_backward(x, start, 2 * k + 1)

	def bisect_backward(self, x, start=None):
		if start:
			ret = self._bisect_backward(x, start, 0)
		else:
			ret = self._bisect_backward(x, self.n, 0)
		self._acc = self.e
		return ret
n = int(input())
query = []
seen = set([0])
for _ in range(n):
	(kind, val) = map(int, input().split())
	query.append((kind, val))
	if val > 0:
		seen.add(val)
unique = list(seen)
unique.sort()
comp = {val: i for (i, val) in enumerate(unique)}
decomp = {i: val for (i, val) in enumerate(unique)}
decopm = {}
nn = len(comp)
base = [0] * nn
STfire = SegmentTree(base)
STnum = SegmentTree(base)
STval = SegmentTree(base)
tnum = 0
fnum = 0
spell = 0
total = 0
for (kind, val) in query:
	cd = comp[abs(val)]
	if val > 0:
		STval.update(cd, val)
		STnum.update(cd, 1)
		total += val
		if kind == 1:
			tnum += 1
		else:
			STfire.update(cd, 1)
			fnum += 1
	else:
		total += val
		STval.update(cd, 0)
		STnum.update(cd, 0)
		if kind == 1:
			tnum -= 1
		else:
			STfire.update(cd, 0)
			fnum -= 1
	spell = tnum + fnum
	if fnum == 0:
		fid = -1
	else:
		fid = STfire.bisect_forward(fnum)
	l = STnum.bisect_forward(spell - tnum)
	if tnum == 0:
		print(total)
		continue
	if fid >= l + 1:
		double_total = STval.fold(l + 1, nn)
		print(total + double_total)
	else:
		l = STnum.bisect_forward(spell - tnum + 1)
		double_total = STval.fold(l + 1, nn)
		if fnum > 0:
			print(total + double_total + decomp[fid])
		else:
			print(total + double_total)


from __future__ import print_function
import sys
import traceback
from bisect import bisect_left, bisect_right, insort
from itertools import chain, repeat, starmap
from math import log
from operator import add, eq, ne, gt, ge, lt, le, iadd
from textwrap import dedent
try:
	from collections.abc import Sequence, MutableSequence
except ImportError:
	from collections import Sequence, MutableSequence
from functools import wraps
from sys import hexversion
if hexversion < 50331648:
	from itertools import imap as map
	from itertools import izip as zip
	try:
		from thread import get_ident
	except ImportError:
		from dummy_thread import get_ident
else:
	from functools import reduce
	try:
		from _thread import get_ident
	except ImportError:
		from _dummy_thread import get_ident

def recursive_repr(fillvalue='...'):

	def decorating_function(user_function):
		repr_running = set()

		@wraps(user_function)
		def wrapper(self):
			key = (id(self), get_ident())
			if key in repr_running:
				return fillvalue
			repr_running.add(key)
			try:
				result = user_function(self)
			finally:
				repr_running.discard(key)
			return result
		return wrapper
	return decorating_function

class SortedList(MutableSequence):
	DEFAULT_LOAD_FACTOR = 1000

	def __init__(self, iterable=None, key=None):
		assert key is None
		self._len = 0
		self._load = self.DEFAULT_LOAD_FACTOR
		self._lists = []
		self._maxes = []
		self._index = []
		self._offset = 0
		if iterable is not None:
			self._update(iterable)

	def __new__(cls, iterable=None, key=None):
		if key is None:
			return object.__new__(cls)
		elif cls is SortedList:
			return object.__new__(SortedKeyList)
		else:
			raise TypeError('inherit SortedKeyList for key argument')

	@property
	def key(self):
		return None

	def _reset(self, load):
		values = reduce(iadd, self._lists, [])
		self._clear()
		self._load = load
		self._update(values)

	def clear(self):
		self._len = 0
		del self._lists[:]
		del self._maxes[:]
		del self._index[:]
		self._offset = 0
	_clear = clear

	def add(self, value):
		_lists = self._lists
		_maxes = self._maxes
		if _maxes:
			pos = bisect_right(_maxes, value)
			if pos == len(_maxes):
				pos -= 1
				_lists[pos].append(value)
				_maxes[pos] = value
			else:
				insort(_lists[pos], value)
			self._expand(pos)
		else:
			_lists.append([value])
			_maxes.append(value)
		self._len += 1

	def _expand(self, pos):
		_load = self._load
		_lists = self._lists
		_index = self._index
		if len(_lists[pos]) > _load << 1:
			_maxes = self._maxes
			_lists_pos = _lists[pos]
			half = _lists_pos[_load:]
			del _lists_pos[_load:]
			_maxes[pos] = _lists_pos[-1]
			_lists.insert(pos + 1, half)
			_maxes.insert(pos + 1, half[-1])
			del _index[:]
		elif _index:
			child = self._offset + pos
			while child:
				_index[child] += 1
				child = child - 1 >> 1
			_index[0] += 1

	def update(self, iterable):
		_lists = self._lists
		_maxes = self._maxes
		values = sorted(iterable)
		if _maxes:
			if len(values) * 4 >= self._len:
				values.extend(chain.from_iterable(_lists))
				values.sort()
				self._clear()
			else:
				_add = self.add
				for val in values:
					_add(val)
				return
		_load = self._load
		_lists.extend((values[pos:pos + _load] for pos in range(0, len(values), _load)))
		_maxes.extend((sublist[-1] for sublist in _lists))
		self._len = len(values)
		del self._index[:]
	_update = update

	def __contains__(self, value):
		_maxes = self._maxes
		if not _maxes:
			return False
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return False
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		return _lists[pos][idx] == value

	def discard(self, value):
		_maxes = self._maxes
		if not _maxes:
			return
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		if _lists[pos][idx] == value:
			self._delete(pos, idx)

	def remove(self, value):
		_maxes = self._maxes
		if not _maxes:
			raise ValueError('{0!r} not in list'.format(value))
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			raise ValueError('{0!r} not in list'.format(value))
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		if _lists[pos][idx] == value:
			self._delete(pos, idx)
		else:
			raise ValueError('{0!r} not in list'.format(value))

	def _delete(self, pos, idx):
		_lists = self._lists
		_maxes = self._maxes
		_index = self._index
		_lists_pos = _lists[pos]
		del _lists_pos[idx]
		self._len -= 1
		len_lists_pos = len(_lists_pos)
		if len_lists_pos > self._load >> 1:
			_maxes[pos] = _lists_pos[-1]
			if _index:
				child = self._offset + pos
				while child > 0:
					_index[child] -= 1
					child = child - 1 >> 1
				_index[0] -= 1
		elif len(_lists) > 1:
			if not pos:
				pos += 1
			prev = pos - 1
			_lists[prev].extend(_lists[pos])
			_maxes[prev] = _lists[prev][-1]
			del _lists[pos]
			del _maxes[pos]
			del _index[:]
			self._expand(prev)
		elif len_lists_pos:
			_maxes[pos] = _lists_pos[-1]
		else:
			del _lists[pos]
			del _maxes[pos]
			del _index[:]

	def _loc(self, pos, idx):
		if not pos:
			return idx
		_index = self._index
		if not _index:
			self._build_index()
		total = 0
		pos += self._offset
		while pos:
			if not pos & 1:
				total += _index[pos - 1]
			pos = pos - 1 >> 1
		return total + idx

	def _pos(self, idx):
		if idx < 0:
			last_len = len(self._lists[-1])
			if -idx <= last_len:
				return (len(self._lists) - 1, last_len + idx)
			idx += self._len
			if idx < 0:
				raise IndexError('list index out of range')
		elif idx >= self._len:
			raise IndexError('list index out of range')
		if idx < len(self._lists[0]):
			return (0, idx)
		_index = self._index
		if not _index:
			self._build_index()
		pos = 0
		child = 1
		len_index = len(_index)
		while child < len_index:
			index_child = _index[child]
			if idx < index_child:
				pos = child
			else:
				idx -= index_child
				pos = child + 1
			child = (pos << 1) + 1
		return (pos - self._offset, idx)

	def _build_index(self):
		row0 = list(map(len, self._lists))
		if len(row0) == 1:
			self._index[:] = row0
			self._offset = 0
			return
		head = iter(row0)
		tail = iter(head)
		row1 = list(starmap(add, zip(head, tail)))
		if len(row0) & 1:
			row1.append(row0[-1])
		if len(row1) == 1:
			self._index[:] = row1 + row0
			self._offset = 1
			return
		size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
		row1.extend(repeat(0, size - len(row1)))
		tree = [row0, row1]
		while len(tree[-1]) > 1:
			head = iter(tree[-1])
			tail = iter(head)
			row = list(starmap(add, zip(head, tail)))
			tree.append(row)
		reduce(iadd, reversed(tree), self._index)
		self._offset = size * 2 - 1

	def __delitem__(self, index):
		if isinstance(index, slice):
			(start, stop, step) = index.indices(self._len)
			if step == 1 and start < stop:
				if start == 0 and stop == self._len:
					return self._clear()
				elif self._len <= 8 * (stop - start):
					values = self._getitem(slice(None, start))
					if stop < self._len:
						values += self._getitem(slice(stop, None))
					self._clear()
					return self._update(values)
			indices = range(start, stop, step)
			if step > 0:
				indices = reversed(indices)
			(_pos, _delete) = (self._pos, self._delete)
			for index in indices:
				(pos, idx) = _pos(index)
				_delete(pos, idx)
		else:
			(pos, idx) = self._pos(index)
			self._delete(pos, idx)

	def __getitem__(self, index):
		_lists = self._lists
		if isinstance(index, slice):
			(start, stop, step) = index.indices(self._len)
			if step == 1 and start < stop:
				if start == 0 and stop == self._len:
					return reduce(iadd, self._lists, [])
				(start_pos, start_idx) = self._pos(start)
				start_list = _lists[start_pos]
				stop_idx = start_idx + stop - start
				if len(start_list) >= stop_idx:
					return start_list[start_idx:stop_idx]
				if stop == self._len:
					stop_pos = len(_lists) - 1
					stop_idx = len(_lists[stop_pos])
				else:
					(stop_pos, stop_idx) = self._pos(stop)
				prefix = _lists[start_pos][start_idx:]
				middle = _lists[start_pos + 1:stop_pos]
				result = reduce(iadd, middle, prefix)
				result += _lists[stop_pos][:stop_idx]
				return result
			if step == -1 and start > stop:
				result = self._getitem(slice(stop + 1, start + 1))
				result.reverse()
				return result
			indices = range(start, stop, step)
			return list((self._getitem(index) for index in indices))
		else:
			if self._len:
				if index == 0:
					return _lists[0][0]
				elif index == -1:
					return _lists[-1][-1]
			else:
				raise IndexError('list index out of range')
			if 0 <= index < len(_lists[0]):
				return _lists[0][index]
			len_last = len(_lists[-1])
			if -len_last < index < 0:
				return _lists[-1][len_last + index]
			(pos, idx) = self._pos(index)
			return _lists[pos][idx]
	_getitem = __getitem__

	def __setitem__(self, index, value):
		message = 'use ``del sl[index]`` and ``sl.add(value)`` instead'
		raise NotImplementedError(message)

	def __iter__(self):
		return chain.from_iterable(self._lists)

	def __reversed__(self):
		return chain.from_iterable(map(reversed, reversed(self._lists)))

	def reverse(self):
		raise NotImplementedError('use ``reversed(sl)`` instead')

	def islice(self, start=None, stop=None, reverse=False):
		_len = self._len
		if not _len:
			return iter(())
		(start, stop, _) = slice(start, stop).indices(self._len)
		if start >= stop:
			return iter(())
		_pos = self._pos
		(min_pos, min_idx) = _pos(start)
		if stop == _len:
			max_pos = len(self._lists) - 1
			max_idx = len(self._lists[-1])
		else:
			(max_pos, max_idx) = _pos(stop)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)

	def _islice(self, min_pos, min_idx, max_pos, max_idx, reverse):
		_lists = self._lists
		if min_pos > max_pos:
			return iter(())
		if min_pos == max_pos:
			if reverse:
				indices = reversed(range(min_idx, max_idx))
				return map(_lists[min_pos].__getitem__, indices)
			indices = range(min_idx, max_idx)
			return map(_lists[min_pos].__getitem__, indices)
		next_pos = min_pos + 1
		if next_pos == max_pos:
			if reverse:
				min_indices = range(min_idx, len(_lists[min_pos]))
				max_indices = range(max_idx)
				return chain(map(_lists[max_pos].__getitem__, reversed(max_indices)), map(_lists[min_pos].__getitem__, reversed(min_indices)))
			min_indices = range(min_idx, len(_lists[min_pos]))
			max_indices = range(max_idx)
			return chain(map(_lists[min_pos].__getitem__, min_indices), map(_lists[max_pos].__getitem__, max_indices))
		if reverse:
			min_indices = range(min_idx, len(_lists[min_pos]))
			sublist_indices = range(next_pos, max_pos)
			sublists = map(_lists.__getitem__, reversed(sublist_indices))
			max_indices = range(max_idx)
			return chain(map(_lists[max_pos].__getitem__, reversed(max_indices)), chain.from_iterable(map(reversed, sublists)), map(_lists[min_pos].__getitem__, reversed(min_indices)))
		min_indices = range(min_idx, len(_lists[min_pos]))
		sublist_indices = range(next_pos, max_pos)
		sublists = map(_lists.__getitem__, sublist_indices)
		max_indices = range(max_idx)
		return chain(map(_lists[min_pos].__getitem__, min_indices), chain.from_iterable(sublists), map(_lists[max_pos].__getitem__, max_indices))

	def irange(self, minimum=None, maximum=None, inclusive=(True, True), reverse=False):
		_maxes = self._maxes
		if not _maxes:
			return iter(())
		_lists = self._lists
		if minimum is None:
			min_pos = 0
			min_idx = 0
		elif inclusive[0]:
			min_pos = bisect_left(_maxes, minimum)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_left(_lists[min_pos], minimum)
		else:
			min_pos = bisect_right(_maxes, minimum)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_right(_lists[min_pos], minimum)
		if maximum is None:
			max_pos = len(_maxes) - 1
			max_idx = len(_lists[max_pos])
		elif inclusive[1]:
			max_pos = bisect_right(_maxes, maximum)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_lists[max_pos])
			else:
				max_idx = bisect_right(_lists[max_pos], maximum)
		else:
			max_pos = bisect_left(_maxes, maximum)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_lists[max_pos])
			else:
				max_idx = bisect_left(_lists[max_pos], maximum)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)

	def __len__(self):
		return self._len

	def bisect_left(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return self._len
		idx = bisect_left(self._lists[pos], value)
		return self._loc(pos, idx)

	def bisect_right(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_right(_maxes, value)
		if pos == len(_maxes):
			return self._len
		idx = bisect_right(self._lists[pos], value)
		return self._loc(pos, idx)
	bisect = bisect_right
	_bisect_right = bisect_right

	def count(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos_left = bisect_left(_maxes, value)
		if pos_left == len(_maxes):
			return 0
		_lists = self._lists
		idx_left = bisect_left(_lists[pos_left], value)
		pos_right = bisect_right(_maxes, value)
		if pos_right == len(_maxes):
			return self._len - self._loc(pos_left, idx_left)
		idx_right = bisect_right(_lists[pos_right], value)
		if pos_left == pos_right:
			return idx_right - idx_left
		right = self._loc(pos_right, idx_right)
		left = self._loc(pos_left, idx_left)
		return right - left

	def copy(self):
		return self.__class__(self)
	__copy__ = copy

	def append(self, value):
		raise NotImplementedError('use ``sl.add(value)`` instead')

	def extend(self, values):
		raise NotImplementedError('use ``sl.update(values)`` instead')

	def insert(self, index, value):
		raise NotImplementedError('use ``sl.add(value)`` instead')

	def pop(self, index=-1):
		if not self._len:
			raise IndexError('pop index out of range')
		_lists = self._lists
		if index == 0:
			val = _lists[0][0]
			self._delete(0, 0)
			return val
		if index == -1:
			pos = len(_lists) - 1
			loc = len(_lists[pos]) - 1
			val = _lists[pos][loc]
			self._delete(pos, loc)
			return val
		if 0 <= index < len(_lists[0]):
			val = _lists[0][index]
			self._delete(0, index)
			return val
		len_last = len(_lists[-1])
		if -len_last < index < 0:
			pos = len(_lists) - 1
			loc = len_last + index
			val = _lists[pos][loc]
			self._delete(pos, loc)
			return val
		(pos, idx) = self._pos(index)
		val = _lists[pos][idx]
		self._delete(pos, idx)
		return val

	def index(self, value, start=None, stop=None):
		_len = self._len
		if not _len:
			raise ValueError('{0!r} is not in list'.format(value))
		if start is None:
			start = 0
		if start < 0:
			start += _len
		if start < 0:
			start = 0
		if stop is None:
			stop = _len
		if stop < 0:
			stop += _len
		if stop > _len:
			stop = _len
		if stop <= start:
			raise ValueError('{0!r} is not in list'.format(value))
		_maxes = self._maxes
		pos_left = bisect_left(_maxes, value)
		if pos_left == len(_maxes):
			raise ValueError('{0!r} is not in list'.format(value))
		_lists = self._lists
		idx_left = bisect_left(_lists[pos_left], value)
		if _lists[pos_left][idx_left] != value:
			raise ValueError('{0!r} is not in list'.format(value))
		stop -= 1
		left = self._loc(pos_left, idx_left)
		if start <= left:
			if left <= stop:
				return left
		else:
			right = self._bisect_right(value) - 1
			if start <= right:
				return start
		raise ValueError('{0!r} is not in list'.format(value))

	def __add__(self, other):
		values = reduce(iadd, self._lists, [])
		values.extend(other)
		return self.__class__(values)
	__radd__ = __add__

	def __iadd__(self, other):
		self._update(other)
		return self

	def __mul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		return self.__class__(values)
	__rmul__ = __mul__

	def __imul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		self._clear()
		self._update(values)
		return self

	def __make_cmp(seq_op, symbol, doc):

		def comparer(self, other):
			if not isinstance(other, Sequence):
				return NotImplemented
			self_len = self._len
			len_other = len(other)
			if self_len != len_other:
				if seq_op is eq:
					return False
				if seq_op is ne:
					return True
			for (alpha, beta) in zip(self, other):
				if alpha != beta:
					return seq_op(alpha, beta)
			return seq_op(self_len, len_other)
		seq_op_name = seq_op.__name__
		comparer.__name__ = '__{0}__'.format(seq_op_name)
		doc_str = 'Return true if and only if sorted list is {0} `other`.\n\n        ``sl.__{1}__(other)`` <==> ``sl {2} other``\n\n        Comparisons use lexicographical order as with sequences.\n\n        Runtime complexity: `O(n)`\n\n        :param other: `other` sequence\n        :return: true if sorted list is {0} `other`\n\n        '
		comparer.__doc__ = dedent(doc_str.format(doc, seq_op_name, symbol))
		return comparer
	__eq__ = __make_cmp(eq, '==', 'equal to')
	__ne__ = __make_cmp(ne, '!=', 'not equal to')
	__lt__ = __make_cmp(lt, '<', 'less than')
	__gt__ = __make_cmp(gt, '>', 'greater than')
	__le__ = __make_cmp(le, '<=', 'less than or equal to')
	__ge__ = __make_cmp(ge, '>=', 'greater than or equal to')
	__make_cmp = staticmethod(__make_cmp)

	def __reduce__(self):
		values = reduce(iadd, self._lists, [])
		return (type(self), (values,))

	@recursive_repr()
	def __repr__(self):
		return '{0}({1!r})'.format(type(self).__name__, list(self))

	def _check(self):
		try:
			assert self._load >= 4
			assert len(self._maxes) == len(self._lists)
			assert self._len == sum((len(sublist) for sublist in self._lists))
			for sublist in self._lists:
				for pos in range(1, len(sublist)):
					assert sublist[pos - 1] <= sublist[pos]
			for pos in range(1, len(self._lists)):
				assert self._lists[pos - 1][-1] <= self._lists[pos][0]
			for pos in range(len(self._maxes)):
				assert self._maxes[pos] == self._lists[pos][-1]
			double = self._load << 1
			assert all((len(sublist) <= double for sublist in self._lists))
			half = self._load >> 1
			for pos in range(0, len(self._lists) - 1):
				assert len(self._lists[pos]) >= half
			if self._index:
				assert self._len == self._index[0]
				assert len(self._index) == self._offset + len(self._lists)
				for pos in range(len(self._lists)):
					leaf = self._index[self._offset + pos]
					assert leaf == len(self._lists[pos])
				for pos in range(self._offset):
					child = (pos << 1) + 1
					if child >= len(self._index):
						assert self._index[pos] == 0
					elif child + 1 == len(self._index):
						assert self._index[pos] == self._index[child]
					else:
						child_sum = self._index[child] + self._index[child + 1]
						assert child_sum == self._index[pos]
		except:
			traceback.print_exc(file=sys.stdout)
			print('len', self._len)
			print('load', self._load)
			print('offset', self._offset)
			print('len_index', len(self._index))
			print('index', self._index)
			print('len_maxes', len(self._maxes))
			print('maxes', self._maxes)
			print('len_lists', len(self._lists))
			print('lists', self._lists)
			raise

def identity(value):
	return value

class SortedKeyList(SortedList):

	def __init__(self, iterable=None, key=identity):
		self._key = key
		self._len = 0
		self._load = self.DEFAULT_LOAD_FACTOR
		self._lists = []
		self._keys = []
		self._maxes = []
		self._index = []
		self._offset = 0
		if iterable is not None:
			self._update(iterable)

	def __new__(cls, iterable=None, key=identity):
		return object.__new__(cls)

	@property
	def key(self):
		return self._key

	def clear(self):
		self._len = 0
		del self._lists[:]
		del self._keys[:]
		del self._maxes[:]
		del self._index[:]
	_clear = clear

	def add(self, value):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		key = self._key(value)
		if _maxes:
			pos = bisect_right(_maxes, key)
			if pos == len(_maxes):
				pos -= 1
				_lists[pos].append(value)
				_keys[pos].append(key)
				_maxes[pos] = key
			else:
				idx = bisect_right(_keys[pos], key)
				_lists[pos].insert(idx, value)
				_keys[pos].insert(idx, key)
			self._expand(pos)
		else:
			_lists.append([value])
			_keys.append([key])
			_maxes.append(key)
		self._len += 1

	def _expand(self, pos):
		_lists = self._lists
		_keys = self._keys
		_index = self._index
		if len(_keys[pos]) > self._load << 1:
			_maxes = self._maxes
			_load = self._load
			_lists_pos = _lists[pos]
			_keys_pos = _keys[pos]
			half = _lists_pos[_load:]
			half_keys = _keys_pos[_load:]
			del _lists_pos[_load:]
			del _keys_pos[_load:]
			_maxes[pos] = _keys_pos[-1]
			_lists.insert(pos + 1, half)
			_keys.insert(pos + 1, half_keys)
			_maxes.insert(pos + 1, half_keys[-1])
			del _index[:]
		elif _index:
			child = self._offset + pos
			while child:
				_index[child] += 1
				child = child - 1 >> 1
			_index[0] += 1

	def update(self, iterable):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		values = sorted(iterable, key=self._key)
		if _maxes:
			if len(values) * 4 >= self._len:
				values.extend(chain.from_iterable(_lists))
				values.sort(key=self._key)
				self._clear()
			else:
				_add = self.add
				for val in values:
					_add(val)
				return
		_load = self._load
		_lists.extend((values[pos:pos + _load] for pos in range(0, len(values), _load)))
		_keys.extend((list(map(self._key, _list)) for _list in _lists))
		_maxes.extend((sublist[-1] for sublist in _keys))
		self._len = len(values)
		del self._index[:]
	_update = update

	def __contains__(self, value):
		_maxes = self._maxes
		if not _maxes:
			return False
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return False
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return False
			if _lists[pos][idx] == value:
				return True
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return False
				len_sublist = len(_keys[pos])
				idx = 0

	def discard(self, value):
		_maxes = self._maxes
		if not _maxes:
			return
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return
			if _lists[pos][idx] == value:
				self._delete(pos, idx)
				return
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return
				len_sublist = len(_keys[pos])
				idx = 0

	def remove(self, value):
		_maxes = self._maxes
		if not _maxes:
			raise ValueError('{0!r} not in list'.format(value))
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			raise ValueError('{0!r} not in list'.format(value))
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				raise ValueError('{0!r} not in list'.format(value))
			if _lists[pos][idx] == value:
				self._delete(pos, idx)
				return
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					raise ValueError('{0!r} not in list'.format(value))
				len_sublist = len(_keys[pos])
				idx = 0

	def _delete(self, pos, idx):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		_index = self._index
		keys_pos = _keys[pos]
		lists_pos = _lists[pos]
		del keys_pos[idx]
		del lists_pos[idx]
		self._len -= 1
		len_keys_pos = len(keys_pos)
		if len_keys_pos > self._load >> 1:
			_maxes[pos] = keys_pos[-1]
			if _index:
				child = self._offset + pos
				while child > 0:
					_index[child] -= 1
					child = child - 1 >> 1
				_index[0] -= 1
		elif len(_keys) > 1:
			if not pos:
				pos += 1
			prev = pos - 1
			_keys[prev].extend(_keys[pos])
			_lists[prev].extend(_lists[pos])
			_maxes[prev] = _keys[prev][-1]
			del _lists[pos]
			del _keys[pos]
			del _maxes[pos]
			del _index[:]
			self._expand(prev)
		elif len_keys_pos:
			_maxes[pos] = keys_pos[-1]
		else:
			del _lists[pos]
			del _keys[pos]
			del _maxes[pos]
			del _index[:]

	def irange(self, minimum=None, maximum=None, inclusive=(True, True), reverse=False):
		min_key = self._key(minimum) if minimum is not None else None
		max_key = self._key(maximum) if maximum is not None else None
		return self._irange_key(min_key=min_key, max_key=max_key, inclusive=inclusive, reverse=reverse)

	def irange_key(self, min_key=None, max_key=None, inclusive=(True, True), reverse=False):
		_maxes = self._maxes
		if not _maxes:
			return iter(())
		_keys = self._keys
		if min_key is None:
			min_pos = 0
			min_idx = 0
		elif inclusive[0]:
			min_pos = bisect_left(_maxes, min_key)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_left(_keys[min_pos], min_key)
		else:
			min_pos = bisect_right(_maxes, min_key)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_right(_keys[min_pos], min_key)
		if max_key is None:
			max_pos = len(_maxes) - 1
			max_idx = len(_keys[max_pos])
		elif inclusive[1]:
			max_pos = bisect_right(_maxes, max_key)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_keys[max_pos])
			else:
				max_idx = bisect_right(_keys[max_pos], max_key)
		else:
			max_pos = bisect_left(_maxes, max_key)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_keys[max_pos])
			else:
				max_idx = bisect_left(_keys[max_pos], max_key)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)
	_irange_key = irange_key

	def bisect_left(self, value):
		return self._bisect_key_left(self._key(value))

	def bisect_right(self, value):
		return self._bisect_key_right(self._key(value))
	bisect = bisect_right

	def bisect_key_left(self, key):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return self._len
		idx = bisect_left(self._keys[pos], key)
		return self._loc(pos, idx)
	_bisect_key_left = bisect_key_left

	def bisect_key_right(self, key):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_right(_maxes, key)
		if pos == len(_maxes):
			return self._len
		idx = bisect_right(self._keys[pos], key)
		return self._loc(pos, idx)
	bisect_key = bisect_key_right
	_bisect_key_right = bisect_key_right

	def count(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return 0
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		total = 0
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return total
			if _lists[pos][idx] == value:
				total += 1
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return total
				len_sublist = len(_keys[pos])
				idx = 0

	def copy(self):
		return self.__class__(self, key=self._key)
	__copy__ = copy

	def index(self, value, start=None, stop=None):
		_len = self._len
		if not _len:
			raise ValueError('{0!r} is not in list'.format(value))
		if start is None:
			start = 0
		if start < 0:
			start += _len
		if start < 0:
			start = 0
		if stop is None:
			stop = _len
		if stop < 0:
			stop += _len
		if stop > _len:
			stop = _len
		if stop <= start:
			raise ValueError('{0!r} is not in list'.format(value))
		_maxes = self._maxes
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			raise ValueError('{0!r} is not in list'.format(value))
		stop -= 1
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				raise ValueError('{0!r} is not in list'.format(value))
			if _lists[pos][idx] == value:
				loc = self._loc(pos, idx)
				if start <= loc <= stop:
					return loc
				elif loc > stop:
					break
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					raise ValueError('{0!r} is not in list'.format(value))
				len_sublist = len(_keys[pos])
				idx = 0
		raise ValueError('{0!r} is not in list'.format(value))

	def __add__(self, other):
		values = reduce(iadd, self._lists, [])
		values.extend(other)
		return self.__class__(values, key=self._key)
	__radd__ = __add__

	def __mul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		return self.__class__(values, key=self._key)

	def __reduce__(self):
		values = reduce(iadd, self._lists, [])
		return (type(self), (values, self.key))

	@recursive_repr()
	def __repr__(self):
		type_name = type(self).__name__
		return '{0}({1!r}, key={2!r})'.format(type_name, list(self), self._key)

	def _check(self):
		try:
			assert self._load >= 4
			assert len(self._maxes) == len(self._lists) == len(self._keys)
			assert self._len == sum((len(sublist) for sublist in self._lists))
			for sublist in self._keys:
				for pos in range(1, len(sublist)):
					assert sublist[pos - 1] <= sublist[pos]
			for pos in range(1, len(self._keys)):
				assert self._keys[pos - 1][-1] <= self._keys[pos][0]
			for (val_sublist, key_sublist) in zip(self._lists, self._keys):
				assert len(val_sublist) == len(key_sublist)
				for (val, key) in zip(val_sublist, key_sublist):
					assert self._key(val) == key
			for pos in range(len(self._maxes)):
				assert self._maxes[pos] == self._keys[pos][-1]
			double = self._load << 1
			assert all((len(sublist) <= double for sublist in self._lists))
			half = self._load >> 1
			for pos in range(0, len(self._lists) - 1):
				assert len(self._lists[pos]) >= half
			if self._index:
				assert self._len == self._index[0]
				assert len(self._index) == self._offset + len(self._lists)
				for pos in range(len(self._lists)):
					leaf = self._index[self._offset + pos]
					assert leaf == len(self._lists[pos])
				for pos in range(self._offset):
					child = (pos << 1) + 1
					if child >= len(self._index):
						assert self._index[pos] == 0
					elif child + 1 == len(self._index):
						assert self._index[pos] == self._index[child]
					else:
						child_sum = self._index[child] + self._index[child + 1]
						assert child_sum == self._index[pos]
		except:
			traceback.print_exc(file=sys.stdout)
			print('len', self._len)
			print('load', self._load)
			print('offset', self._offset)
			print('len_index', len(self._index))
			print('index', self._index)
			print('len_maxes', len(self._maxes))
			print('maxes', self._maxes)
			print('len_keys', len(self._keys))
			print('keys', self._keys)
			print('len_lists', len(self._lists))
			print('lists', self._lists)
			raise
SortedListWithKey = SortedKeyList
from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def linc(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t > f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rinc(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t < f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def ldec(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t < f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rdec(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t > f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def binfun(x):
	c = 0
	for w in arr:
		c += ceil(w / x)
	return c

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return prime

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [(ch, len(list(g))) for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None
t = 1
for i in range(t):
	n = N()
	s1 = SortedList()
	s2 = SortedList()
	f = 0
	cs = cs1 = 0
	cur = 0
	for i in range(n):
		(tp, d) = RL()
		cs += d
		if d > 0:
			if tp == 1:
				s2.add((d, 1))
				tmp = s2.pop()
				s1.add(tmp)
				cs1 += tmp[0]
				f += 1 - tmp[1]
			elif s1 and s1[0][0] < d:
				tmp = s1.pop(0)
				cs1 -= tmp[0]
				f -= 1 - tmp[1]
				s1.add((d, 0))
				f += 1
				cs1 += d
				s2.add(tmp)
			else:
				s2.add((d, 0))
		else:
			d = -d
			if tp == 1:
				if (d, 1) in s1:
					cs1 -= d
					s1.remove((d, 1))
				else:
					s2.remove((d, 1))
					tmp = s1.pop(0)
					cs1 -= tmp[0]
					f -= 1 - tmp[1]
					s2.add(tmp)
			elif (d, 0) in s1:
				cs1 -= d
				s1.remove((d, 0))
				f -= 1
				tmp = s2.pop()
				f += 1 - tmp[1]
				cs1 += tmp[0]
				s1.add(tmp)
			else:
				s2.remove((d, 0))
		ans = cs1 + cs
		if not f and s1:
			ans -= s1[0][0]
			if s2:
				ans += s2[-1][0]
		print(ans)


import io
import os
from collections import Counter, defaultdict, deque

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def solve(N, queries):
	L = SortedList()
	F = SortedList()
	sumL = 0
	sumF = 0
	sumDouble = 0
	double = SortedList()
	overflow = SortedList()
	smallestL = None

	def fix():
		nonlocal sumF, sumL, sumDouble, smallestL
		while len(double) > len(L):
			temp = double[0]
			double.remove(temp)
			sumDouble -= temp
			overflow.add(temp)
		while len(double) < len(L) and len(overflow):
			temp = overflow[-1]
			overflow.remove(temp)
			double.add(temp)
			sumDouble += temp
		if False:
			assert sum(L) == sumL
			assert sum(F) == sumF
			assert sum(double) == sumDouble
			if L:
				assert smallestL == L[0]
			else:
				assert smallestL is None
			assert sorted(list(L)[1:] + list(F)) == sorted(list(double) + list(overflow))

	def add(d, tp):
		nonlocal sumF, sumL, sumDouble, smallestL
		toAdd = d
		if tp == 0:
			F.add(d)
			sumF += d
		else:
			if not L or L[0] > d:
				toAdd = smallestL
				smallestL = d
			L.add(d)
			sumL += d
		if toAdd is not None:
			if not double or toAdd > double[0]:
				double.add(toAdd)
				sumDouble += toAdd
			else:
				overflow.add(toAdd)
		fix()

	def remove(d, tp):
		nonlocal sumF, sumL, sumDouble, smallestL
		toRemove = d
		if tp == 0:
			F.remove(d)
			sumF -= d
		else:
			L.remove(d)
			sumL -= d
			smallestL = None if not L else L[0]
			if not L or smallestL > d:
				toRemove = smallestL
		if toRemove is not None:
			if toRemove in overflow:
				overflow.remove(toRemove)
			else:
				double.remove(toRemove)
				sumDouble -= toRemove
		fix()
	ans = []
	for (tp, d) in queries:
		if d > 0:
			add(d, tp)
		else:
			remove(-d, tp)
		ans.append(sumDouble + sumL + sumF)
	return '\n'.join(map(str, ans))
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N,) = [int(x) for x in input().split()]
queries = ((int(x) for x in input().split()) for i in range(N))
ans = solve(N, queries)
print(ans)