Bessie and the cows are playing with sequences and need your help. They start with a sequence, initially containing just the number 0, and perform n operations. Each operation is one of the following:

  1. Add the integer xi to the first ai elements of the sequence. 
  2. Append an integer ki to the end of the sequence. (And hence the size of the sequence increases by 1) 
  3. Remove the last element of the sequence. So, the size of the sequence decreases by one. Note, that this operation can only be done if there are at least two elements in the sequence. 



After each operation, the cows would like to know the average of all the numbers in the sequence. Help them!

Input

The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of operations. The next n lines describe the operations. Each line will start with an integer ti (1 ≤ ti ≤ 3), denoting the type of the operation (see above). If ti = 1, it will be followed by two integers ai, xi (|xi| ≤ 103; 1 ≤ ai). If ti = 2, it will be followed by a single integer ki (|ki| ≤ 103). If ti = 3, it will not be followed by anything.

It is guaranteed that all operations are correct (don't touch nonexistent elements) and that there will always be at least one element in the sequence.

Output

Output n lines each containing the average of the numbers in the sequence after the corresponding operation.

The answer will be considered correct if its absolute or relative error doesn't exceed 10 - 6.

Examples

Input

5
2 1
3
2 3
2 1
3


Output

0.500000
0.000000
1.500000
1.333333
1.500000


Input

6
2 1
1 2 20
2 2
1 2 -3
3
3


Output

0.500000
20.500000
14.333333
12.333333
17.500000
17.000000

Note

In the second sample, the sequence becomes <image>
import java.util.*; 
import java.io.*;

/*
  This is an implementation of a recursive splaying algorithm.
  It depends on "deep splay" to keep the tree balanced
  preventing stack overflow on the splays, and guaranteeing O(log n)
  worst case time.  It's also totally functional.  i.e. the trees are
  persistent.  It uses the snip/glue paradigm to easily incorporate 
  complicated augmentations.

  Removed the "functional" part of this to see if it's more efficient.
*/

public class AA {
    static class Node {
	Node l, r;
	int size, depth;
	int delta;
	int key;
	Node(Node lx, int k, int d, Node rx, int ss, int dd) {
	    key = k;
	    delta = d;
	    l = lx;
	    r = rx;
	    size = ss;
	    depth = dd;
	}
    }
    
    static Node copy(Node n) {
	return new Node (n.l, n.key, n.delta, n.r, n.size, n.depth);
    }

    private static Node nullNode;
    static {
	nullNode = new Node(null, 0, 0, null, 0, 0);
    }

    static Node connect(Node ll, Node k, Node rr) {
	//	return new Node(ll, k.key, k.delta, rr, 1, 1);
	k.l = ll;
	k.r = rr;
	return k;
    }

    static Node glue(Node ll, Node k, Node rr) {
	if (ll != nullNode) ll.delta -= k.delta;
	if (rr != nullNode) rr.delta -= k.delta;
	k.size = ll.size + 1 + rr.size;
	k.depth = 1 + Math.max(ll.depth, rr.depth);
	k.l = ll;
	k.r = rr;
	return k;
    }

    static Node snip(Node n) {
	Node l=n.l,  r=n.r;
	if (l != nullNode) l.delta += n.delta;
	if (r != nullNode) r.delta += n.delta;
	n.key += n.delta;
	n.delta = 0;
	n.size = n.depth = 1;
	return n;
    }

    //    static Node nodeOfRank(Node t, int rank) {
    //	int lsize = t.l.size;
    //	if (rank < lsize) return nodeOfRank(t.l, rank);
    //	else if (rank > lsize) return nodeOfRank(t.r, rank-lsize-1);
    //	else return t;
    //    }

    static Node splayRank(Node t, int rank) {
	/* t is already snipped.  returns a splayed tree, which is in the snipped state */
	if (rank == t.l.size) return t;
	if (rank < t.l.size) {
	    Node u = snip(t.l);
	    if (rank == u.l.size) return connect(u.l, u, glue(u.r, t, t.r));
	    if (rank < u.l.size) {
		Node v = snip(u.l);
		v = splayRank(v, rank);
		return connect(v.l, v, glue(v.r, u, glue(u.r, t, t.r)));
	    } else {
		u = splayRank(u, rank);
		return connect(u.l, u, glue(u.r, t, t.r));		
	    }
	} else {
	    rank -= t.l.size+1;
	    Node u = snip(t.r);
	    if (rank == u.l.size) return connect(glue(t.l, t, u.l), u, u.r);
	    if (rank > u.l.size) {
		Node v = snip(u.r);
		v = splayRank(v, rank - (u.l.size+1));
		return connect(glue(glue(t.l, t, u.l), u, v.l), v, v.r);
	    } else {
		u = splayRank(u, rank);
		return connect(glue(t.l, t, u.l), u, u.r);
	    }
	}
    }

    static Node splay(Node t, int rank) {
	if (t == nullNode) return t;
	t = splayRank(snip(t), rank);
	return glue (t.l, t, t.r);
    }
    
    static int rankOfDeepest(Node t, int ac) {
	if (t.depth == 1) return ac;
	if (t.l.depth >= t.r.depth) return rankOfDeepest(t.l, ac);
	return rankOfDeepest(t.r, ac+t.l.size+1);
    }

    static Node deepSplay(Node t) {
	if (t == nullNode) return t;
	return splay(t, rankOfDeepest(t,0));
    }

    static Node append(Node t, int key) {
	Node n = new Node(nullNode, key, 0, nullNode, 1, 1);
	n = glue(t, n, nullNode);
	return deepSplay(n);
    }

    static void printTree(Node t, int d) {
	if (t == nullNode) return;
	printTree(t.r, d+1);
	for (int i=0; i<d; i++) System.out.printf("    ");
	System.out.printf("(%d, %d, %d) \n", t.key, t.size, t.depth);
	printTree(t.l, d+1);
    }

    public void read_input_and_solve() throws IOException, MyException {
	StringBuilder out = new StringBuilder();

	long total = 0;
	Node t = append(nullNode, 0);
	int n = nextInt();

	for (int i=0; i<n; i++) {
	    int c = nextInt();
	    if (c==1) {
		int a = nextInt();
		int x = nextInt();
		t = splay(t, a-1);
		t.delta += x;
		if (t.r != nullNode) t.r.delta -= x;
		total += a*x;
	    } else if (c==2) {
		int k = nextInt();
		total += k;
		t = append(t, k);
	    } else {
		t = splay(t, t.size-1);
		t = snip(t);
		total -= t.key;
		t = t.l;
	    }
	    out.append(String.format("%.6f\n", (total + 0.0) / t.size));
//	    if (i%5 == 0) t = deepSplay(t);
	}
	System.out.print(out);	    
    }

    public static void main(String[] args) {
	(new AA()).run();
    }
    
    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;
    
    public void run() {
	try {
	    reader = new BufferedReader(new InputStreamReader(System.in));
	    tokenizer = null;
	    writer = new PrintWriter(System.out);
	    read_input_and_solve();
	    reader.close();
	    writer.close();
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
    }
    
    int nextInt() throws IOException {
	return Integer.parseInt(nextToken());
    }
    
    long nextLong() throws IOException {
	return Long.parseLong(nextToken());
    }
    
    double nextDouble() throws IOException {
	return Double.parseDouble(nextToken());
    }
    
    String nextToken() throws IOException {
	while (tokenizer == null || !tokenizer.hasMoreTokens()) {
	    tokenizer = new StringTokenizer(reader.readLine());
	}
	return tokenizer.nextToken();
    }
}

class MyException extends Exception {
    public String s;
    public MyException(String prob) {
	super(prob);
	s = prob;
    }
}