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.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class TC
{
    static int N;
    static long[] a;
    static SegmentTree tree;
    static int cnt;
    
    static void q1( int xi, int ai )
    {
        tree.addRange(0, ai-1, xi);
    }
    
    static void q2( int ki )
    {
        tree.addRange(cnt, cnt, ki);
        cnt++;
    }
    
    static void q3( )
    {
        long val=tree.RMQ(cnt-1, cnt-1);
        tree.addRange(cnt-1, cnt-1, -val);
        cnt--;
    }
    
    static void init()
    {
        a=new long[N+1];
        Arrays.fill( a, 0 );
        tree=new SegmentTree(a);
        cnt=1;
    }
    
    public static void main( String[] args ) throws IOException
    {
        BufferedReader br=new BufferedReader( new InputStreamReader( System.in ));
        N=Integer.parseInt( br.readLine() );
        BufferedWriter out=new BufferedWriter( new OutputStreamWriter( System.out ));
        init();
        for( int i=0; i<N; i++ )
        {
            String s=br.readLine();
            StringTokenizer tok=new StringTokenizer(s);
            int t=Integer.parseInt(tok.nextToken());
            if( t==1 )
            {
                int ai=Integer.parseInt(tok.nextToken());
                int xi=Integer.parseInt(tok.nextToken());
                q1( xi, ai );
            }
            else if( t==2 )
            {
                int ki=Integer.parseInt(tok.nextToken());
                q2( ki );
            }
            else if( t==3 )
            {
                q3();
            }
            //tree.printTree();
            long SUM=tree.RMQ(0, cnt-1);
            double res=SUM*(1.0)/cnt;
            //out.write( Double.toString(res) + "\n");
            System.out.println(res);
        }
        
        out.close();
    }
    
    
}


class SegmentTree{


    private long[] arr;
    private long[] s_tree;
    private long[] add;
    private int n;
    private boolean[] dirty;

    public void printTree()
    {
        for( int i=0; i<s_tree.length; i++ )
        {
            System.out.print( s_tree[ i ] + " ");
        }
        System.out.println();
    }

    private void fillTree( ){

        double logne = Math.log( n );
        double log2e = Math.log( 2 );

        double logn_ceil = ( int ) Math.ceil( logne / log2e );

        int length =  2*( ( int ) Math.pow( 2, logn_ceil ));
        s_tree = new long[ length + 100 ];
        dirty = new boolean[ length+ 100 ];
        add = new long[ length+ 100 ];

        Arrays.fill( s_tree, 0 );
        Arrays.fill( dirty, false );
        Arrays.fill( add, 0 );

        initialize( 0, n-1, 1 );

    }

    private void initialize( int a, int b, int i ){


        if( a>b )
            return;

        if( a==b )
        {
            s_tree[ i ] = arr[ b ];
            return;
        }

        int mid = ( a + b )/2;

        initialize( a, mid, 2*i );
        initialize( mid+1, b, 2*i + 1 );


       // if(  arr[ s_tree[ 2*i ] ] <  arr[ s_tree[ 2*i+1 ] ] )
           s_tree[ i ] = s_tree[ 2*i ] + s_tree[ 2*i + 1 ];

//       else
           // s_tree[ i ] = s_tree[ 2*i + 1 ];

    }

    public long RMQ( int a, int b )
    {
        return query( a, b, 0, n-1, 1 );
    }

    public void addRange( int a, int b, long VAL )
    {
        updateRange( a, b, 0, n-1, 1, VAL );
    }
    private void updateRange( int a, int b, int r1, int r2, int i, long VAL )
    {

        if( ( a>r2 ) || ( b < r1 ) )
	return;
        
        // first update current node, push flags downwards IF NEEDED
        
        propagate( i, r1, r2 );
        
        // Now current node is up to date
	// update flags of required range
        
        if( ( a == r1 ) && ( b == r2 ) )
	{
                long diff = 0;
                long oldVal = s_tree[ i ];
                dirty[ i ] = false;
                s_tree[i]+=VAL*( r2-r1+1);
                add[i]=0;
                diff = s_tree[ i ] - oldVal;
		               
                if( 2*i < dirty.length )
                {
                    dirty[ 2*i ] = true;
                    add[2*i]+=VAL;
                }
                
		if( (2*i+1) < dirty.length )
                {
                    dirty[ 2*i + 1 ] = true;
                    add[2*i + 1 ]+=VAL;
                }

		if( diff == 0 )
		return;

		else //trickle up updates
		trickleUp( i/2, diff );

		return;
		
	}

        // now find which child to take

        if( r1 == r2 )
            return;
        
        int mid = ( r1 + r2 )/2;

        // check if it lies completely in one child node

       if( a>mid )
           updateRange( a, b, mid+1, r2, 2*i + 1, VAL );

       else if( b<mid+1 )
           updateRange( a, b, r1, mid, 2*i, VAL );

       // else split ranges as required

       else
       {
            updateRange( a, mid, r1, mid, 2*i, VAL );
            updateRange( mid+1, b, mid+1, r2, 2*i + 1, VAL );
       }

        return;

    }
    
    private void trickleUp( int i, long val )
    {
	while( i>0 )
	{
		s_tree[ i ] += val;
		i = i/2;
	}

	return;
    }   



    private void propagate( int i, int r1, int r2 )
    {
        // first update current node, push flags downwards IF NEEDED

	if( dirty[ i ] == false )
            return;
        
        else
	{
                if( r1 == r2 ) // leaf node, no downward propagate
                {
                    s_tree[i]+=add[i];
                    //arr[i]+=add[i];
                    add[i]=0;
                    dirty[ i ] = false;
                    return;
                }
                
		// else toggle children

                else
                {
                    s_tree[i]+=add[i]*(r2-r1+1);
                    dirty[ i ] = false;
                    dirty[ 2*i ] = true;
                    dirty[ 2*i + 1 ] = true;
                    add[ 2*i ] += add[i];
                    add[ 2*i+1 ] += add[i];
                    add[i]=0;
                }
                
	}

    }
    
    // a, b -> query ranges
    // i -> current node of segment tree
    // r1, r2 -> ranges represented by node i

    
    private long query( int a, int b, int r1, int r2, int i ){

        if( a>b )
            return 0;
        
        if( ( a>r2 ) || ( b<r1 ))
            return 0;
        
    
        propagate( i, r1, r2 );
        // Now current node is up to date

	// Now run query

//        if( a==b )
  //          return arr[ a ]; /// change as reqd, associate with array

        if( ( a==r1 ) && ( b==r2 ) )
            return s_tree[ i ] ;

        
       int mid = ( r1 + r2 )/2;

       // check if it lies completely in one child node

       if( a>mid )
           return query( a, b, mid+1, r2, 2*i + 1 );

       if( b<mid+1 )
           return query( a, b, r1, mid, 2*i );

       // else split ranges as required

       long res1 = query( a, mid, r1, mid, 2*i );
       long res2 = query( mid+1, b, mid+1, r2, 2*i + 1 );

       return res1+res2;

    }


    public SegmentTree( long[] _arr ){



        n = _arr.length;
        arr = _arr;

        fillTree();

        /* for( int temp : s_tree )
            System.out.print( temp + " " );

        System.out.println(); */
    }




}

