#include <bits/stdc++.h>
using namespace std;
long double values[100005];
int n, q;
struct LazyNode {
  long double p, k;
  LazyNode() {
    k = 0;
    p = 1.0;
  }
  void operator+=(const LazyNode &ln) {
    p *= ln.p;
    k = k * ln.p + ln.k;
  }
};
struct Node {
  long double a, b, x;
  Node() {
    a = 1;
    x = 0;
    b = 0;
  }
  void modify(const LazyNode &ln, int l, int r) {
    a *= ln.p;
    b = ln.p * b + ln.k * (r - l + 1);
  }
  Node join(const Node &other) {
    Node c;
    c.x = getSum() + other.a * other.x + other.b;
    c.a = 1;
    c.b = 0;
    return c;
  }
  long double getSum() { return a * x + b; }
};
struct ST {
  Node T[100005 * 4];
  LazyNode LazyT[100005 * 4];
  int n;
  ST() {}
  ST(int tam) {
    n = tam;
    build_tree(0, 0, n - 1);
  }
  void setSizeAndBuild(int tam) {
    n = tam;
    build_tree(0, 0, n - 1);
  }
  void build_tree(int node, int a, int b) {
    if (a == b) {
      LazyT[node] = LazyNode();
      T[node].x = values[a];
      T[node].a = 1;
      T[node].b = 0;
      return;
    }
    build_tree(((node << 1) + 1), a, ((a + b) >> 1)),
        build_tree(((node << 1) + 2), ((a + b) >> 1) + 1, b);
    T[node] = T[((node << 1) + 1)].join(T[((node << 1) + 2)]);
    LazyT[node] = LazyNode();
  }
  void push(int node, int a, int b) {
    T[node].modify(LazyT[node], a, b);
    if (a != b) {
      LazyT[node * 2 + 1] += LazyT[node];
      LazyT[node * 2 + 2] += LazyT[node];
    }
    LazyT[node] = LazyNode();
  }
  Node query(int node, int a, int b, int lo, int hi) {
    push(node, a, b);
    if (lo > b || a > hi) return Node();
    if (a >= lo && hi >= b) return T[node];
    return query(((node << 1) + 1), a, ((a + b) >> 1), lo, hi)
        .join(query(((node << 1) + 2), ((a + b) >> 1) + 1, b, lo, hi));
  }
  void update(int node, int a, int b, int lo, int hi, const LazyNode &val) {
    push(node, a, b);
    if (lo > b || a > hi) return;
    if (a >= lo && hi >= b) {
      LazyT[node] = val;
      push(node, a, b);
      return;
    }
    update(((node << 1) + 1), a, ((a + b) >> 1), lo, hi, val);
    update(((node << 1) + 2), ((a + b) >> 1) + 1, b, lo, hi, val);
    T[node] = T[((node << 1) + 1)].join(T[((node << 1) + 2)]);
  }
  Node query(int lo, int hi) { return query(0, 0, n - 1, lo, hi); }
  void update(int lo, int hi, const LazyNode &val) {
    update(0, 0, n - 1, lo, hi, val);
  }
} st2;
void showValues() {
  puts("");
  for (int i = 0; i < n; i++) {
    Node val = st2.query(i, i);
    cout << (double)val.getSum() << " ";
  }
  cout << "\n";
}
int main() {
  scanf("%d %d", &n, &q);
  for (int i = 0; i < n; i++) {
    int x;
    scanf("%d", &x);
    values[i] = x;
  }
  st2.setSizeAndBuild(n);
  for (int i = 0; i < q; i++) {
    int ty;
    scanf("%d", &ty);
    if (ty == 1) {
      int l1, l2, r1, r2;
      scanf("%d %d", &l1, &r1);
      scanf("%d %d", &l2, &r2);
      l1--;
      r1--;
      l2--;
      r2--;
      int le1 = r1 - l1 + 1;
      int le2 = r2 - l2 + 1;
      Node n1 = st2.query(l1, r1);
      Node n2 = st2.query(l2, r2);
      long double avg1 = n1.getSum() / le1;
      long double avg2 = n2.getSum() / le2;
      long double p1 = (long double)1 / ((long double)le1);
      LazyNode ln1;
      ln1.p = (1 - p1);
      ln1.k = p1 * avg2;
      st2.update(l1, r1, ln1);
      long double p2 = (long double)1 / ((long double)le2);
      LazyNode ln2;
      ln2.p = (1 - p2);
      ln2.k = p2 * avg1;
      st2.update(l2, r2, ln2);
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      l--;
      r--;
      Node node = st2.query(l, r);
      cout << (double)node.getSum() << "\n";
    }
  }
}
