Problem: Vasya and Petya were tired of studying so they decided to play a game. Before the game begins Vasya looks at array a consisting of n integers. As soon as he remembers all elements of a the game begins. Vasya closes his eyes and Petya does q actions of one of two types:

1) Petya says 4 integers l1, r1, l2, r2 — boundaries of two non-intersecting segments. After that he swaps one random element from the [l1, r1] segment with another random element from the [l2, r2] segment.

2) Petya asks Vasya the sum of the elements of a in the [l, r] segment.

Vasya is a mathematician so he answers Petya the mathematical expectation of the sum of the elements in the segment.

Your task is to write a program which will answer the second type questions as Vasya would do it. In other words your program should print the mathematical expectation of the sum of the elements of a in the [l, r] segment for every second type query.

Input

The first line contains two integers n, q (2 ≤ n ≤ 105, 1 ≤ q ≤ 105) — the number of elements in the array and the number of queries you need to handle.

The second line contains n integers ai (1 ≤ ai ≤ 109) — elements of the array.

The next q lines contain Petya's actions of type 1 or 2.

If it is a type 1 action then the line contains 5 integers 1, l1, r1, l2, r2 (1 ≤ l1 ≤ r1 ≤ n, 1 ≤ l2 ≤ r2 ≤ n).

If it is a type 2 query then the line contains 3 integers 2, l, r (1 ≤ l ≤ r ≤ n).

It is guaranteed that there is at least one type 2 query and segments [l1, r1], [l2, r2] don't have common elements. 

Output

For each type 2 query print one real number — the mathematical expectation of the sum of elements in the segment.

Your answer will be considered correct if its absolute or relative error doesn't exceed 10 - 4 — formally, the answer is correct if <image> where x is jury's answer and y is yours.

Examples

Input

4 4
1 1 2 2
1 2 2 3 3
2 1 2
1 1 2 3 4
2 1 2


Output

3.0000000
3.0000000


Input

10 5
1 1 1 1 1 2 2 2 2 2
1 1 5 6 10
2 1 5
1 1 5 6 10
1 1 5 6 10
2 6 10


Output

6.0000000
8.0400000


Input

10 10
1 2 3 4 5 6 7 8 9 10
1 1 5 6 10
1 1 5 6 10
2 1 5
1 1 3 6 9
2 1 3
1 5 7 8 10
1 1 1 10 10
2 1 5
2 7 10
2 1 10


Output

23.0000000
14.0000000
28.0133333
21.5733333
55.0000000

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;

public class Problem
{

    static int mod = (int) (1e9+7);
    static InputReader in;
    static PrintWriter out;
    static long[] arr;
    
    static class SegmentTree {
        double st[];
        double lazy[];
        double lazy1[];
 
        SegmentTree(int n)  {
            st = new double[4*n];
            lazy = new double[4*n];
            lazy1 = new double[4*n];
            build(0, n - 1, 1);
        }

        int getMid(int s, int e) {
            return (s+e)>>1;
        }
        
        void lazyupdate(int ss,int ee,int si){
            if(lazy[si] != 0 && lazy1[si] != 1){
                if(ss != ee){
                    lazy1[2*si] *= lazy1[si];
                    lazy1[2*si+1] *= lazy1[si];
                    lazy[2*si] = lazy[2 * si] * lazy1[si] + lazy[si];
                    lazy[2*si+1] = lazy[2 * si + 1] * lazy1[si] + lazy[si];
                }
                st[si] = st[si] * lazy1[si] + lazy[si] * (ee-ss+1);
                lazy[si] = 0;
                lazy1[si] = 1;
            }
        }

        double merge(double a,double b){
            return a + b;
        }
        
        void update(int s, int e, int x, int y, double c, double d, int si){
            if(s == x && e == y){
                lazy1[si] *= c;
                lazy[si] += d;
            }
            else{
                lazyupdate(s, e, si);
                int mid = getMid(s, e);
                if(y <= mid)    
                    update(s, mid, x, y, c, d, 2*si);
                else if(x > mid)
                    update(mid + 1, e, x ,y ,c , d,2*si + 1);
                else{
                    update(s, mid, x, mid, c, d, 2*si);
                    update(mid + 1, e, mid + 1, y, c, d, 2*si + 1);
                }
                lazyupdate(s, mid, 2*si);
                lazyupdate(mid + 1, e, 2*si + 1);
                st[si] = merge(st[2*si],st[2*si+1]);
            }
        }
        
        double  get(int s, int e, int x, int y, int si){

            lazyupdate(s, e,si);
            if(s == x && e == y){
                return st[si];
            }
            int mid = getMid(s, e);
            if(y <= mid)
                return get(s, mid, x, y, 2*si);
            else if(x > mid)
                return get(mid + 1, e, x, y, 2*si + 1);
            return merge(get(s, mid, x, mid, 2*si), get(mid + 1, e, mid + 1, y, 2*si + 1));
        }

        void build(int ss, int se, int si){
            if (ss == se) {
                st[si] = arr[ss];
                lazy[si] = 0;
                lazy1[si] = 1;
                return;
            }

            int mid = getMid(ss, se);
            build(ss, mid, si * 2 );
            build(mid + 1, se, si * 2 + 1);
            lazy[si] = 0;
            lazy1[si] = 1;
            st[si] = merge(st[2*si],st[2*si+1]);
        }
        
    }
    
    public static void main(String[] args)
    {
        in = new InputReader(System.in);
        out = new PrintWriter(System.out);            
        
        int n = in.nextInt();
        int q = in.nextInt();
        arr = in.nextLongArray(n);
        
        SegmentTree seg = new SegmentTree(n);
        
        for(int i = 0; i < q; i++){
            int t = in.nextInt();
            if(t == 1){
                int l1 = in.nextInt() - 1;
                int r1 = in.nextInt() - 1;
                int l2 = in.nextInt() - 1;
                int r2 = in.nextInt() - 1;
                
                double x1 = seg.get(0, n - 1, l1, r1, 1)/ (r1 - l1 + 1.0);
                double x2 = seg.get(0, n - 1, l2, r2, 1)/ (r2 - l2 + 1.0);
                seg.update(0, n - 1, l1, r1, (r1 - l1 + 0.0) / (r1 - l1 + 1.0), x2 / (r1 - l1 + 1.0), 1);
                seg.update(0, n - 1, l2, r2, (r2 - l2 + 0.0) / (r2 - l2 + 1.0), x1 / (r2 - l2 + 1.0), 1);
            }
            else{
                int l = in.nextInt() - 1;
                int r = in.nextInt() - 1;
                out.println(seg.get(0, n - 1, l, r, 1));
            }
        }
        
        out.close();
        
    }

    static class Pair implements Comparable<Pair>
    {

        int x,y;
        int i;
        long c;

        Pair (int x, long c)
        {
                this.x = x;
                this.c = c;
        }

        Pair (int x,int y)
        {
                this.x = x;
                this.y = y;
        }

        Pair (int x,int y, long c)
        {
                this.x = x;
                this.y = y;
                this.c = c;
        }

        public int compareTo(Pair o)
        {
            return Long.compare(this.x,o.x);
                //return 0;
        }

        public boolean equals(Object o)
        {
            if (o instanceof Pair)
            {
                Pair p = (Pair)o;
                return p.x == x && p.y==y;
            }
            return false;
        }

        @Override
        public String toString()
        {
            return x + " "+ y + " "+c;
        }

        /*public int hashCode()
        {
            return new Long(x).hashCode() * 31 + new Long(y).hashCode();
        }*/

    } 

    static long add(long a,long b){
        long x=(a+b);
        while(x>=mod) x-=mod;
        return x;
    }

    static long sub(long a,long b){
        long x=(a-b);
        while(x<0) x+=mod;
        return x;
    }
    
    static long mul(long a,long b){
        long x=(a*b);
        while(x>=mod) x-=mod;
        return x;
    }
    
    static String rev(String s){
        StringBuilder sb=new StringBuilder(s);
        sb.reverse();
        return sb.toString();
    }
    
    static long gcd(long x,long y)
    {
        if(y==0)
                return x;
        else
                return gcd(y,x%y);
    }

    static int gcd(int x,int y)
    {
        if(y==0)
                return x;
        else 
                return gcd(y,x%y);
    }

    static long pow(long n,long p,long m)
    {
         long  result = 1;
          if(p==0){
            return n;
          }
          
        while(p!=0)
        {
            if(p%2==1)
                result *= n;
            if(result >= m)
               result %= m;
            p >>=1;
            n*=n;
            if(n >= m)
                n%=m;
        }
        
        return result;
    }

    static long pow(long n,long p)
    {
        long  result = 1;
          if(p==0)
            return 1;

        while(p!=0)
        {
            if(p%2==1)
                result *= n;	    
            p >>=1;
            n*=n;	    
        }
        return result;
    }

    static void debug(Object... o)
    {
            System.out.println(Arrays.deepToString(o));
    }

    static class InputReader
    {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
                this.stream = stream;
        }

        public int snext()
        {
                if (snumChars == -1)
                        throw new InputMismatchException();
                if (curChar >= snumChars)
                {
                        curChar = 0;
                        try
                        {
                                snumChars = stream.read(buf);
                        } catch (IOException e)
                        {
                                throw new InputMismatchException();
                        }
                        if (snumChars <= 0)
                                return -1;
                }
                return buf[curChar++];
        }

        public int nextInt()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                int res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public long nextLong()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                int sgn = 1;
                if (c == '-')
                {
                        sgn = -1;
                        c = snext();
                }
                long res = 0;
                do
                {
                        if (c < '0' || c > '9')
                                throw new InputMismatchException();
                        res *= 10;
                        res += c - '0';
                        c = snext();
                } while (!isSpaceChar(c));
                return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
                int a[] = new int[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextInt();
                }
                return a;
        }

        public long[] nextLongArray(int n)
        {
                long a[] = new long[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextLong();
                }
                return a;
        }

        public String readString()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isSpaceChar(c));
                return res.toString();
        }

        public String nextLine()
        {
                int c = snext();
                while (isSpaceChar(c))
                        c = snext();
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isEndOfLine(c));
                return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
                return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
                public boolean isSpaceChar(int ch);
        }

    }
}