Problem: There are n casinos lined in a row. If Memory plays at casino i, he has probability pi to win and move to the casino on the right (i + 1) or exit the row (if i = n), and a probability 1 - pi to lose and move to the casino on the left (i - 1) or also exit the row (if i = 1). 

We say that Memory dominates on the interval i... j if he completes a walk such that,

  * He starts on casino i. 
  * He never looses in casino i. 
  * He finishes his walk by winning in casino j. 



Note that Memory can still walk left of the 1-st casino and right of the casino n and that always finishes the process.

Now Memory has some requests, in one of the following forms:

  * 1 i a b: Set <image>. 
  * 2 l r: Print the probability that Memory will dominate on the interval l... r, i.e. compute the probability that Memory will first leave the segment l... r after winning at casino r, if she starts in casino l. 



It is guaranteed that at any moment of time p is a non-decreasing sequence, i.e. pi ≤ pi + 1 for all i from 1 to n - 1.

Please help Memory by answering all his requests!

Input

The first line of the input contains two integers n and q(1 ≤ n, q ≤ 100 000), — number of casinos and number of requests respectively.

The next n lines each contain integers ai and bi (1 ≤ ai < bi ≤ 109) — <image> is the probability pi of winning in casino i.

The next q lines each contain queries of one of the types specified above (1 ≤ a < b ≤ 109, 1 ≤ i ≤ n, 1 ≤ l ≤ r ≤ n).

It's guaranteed that there will be at least one query of type 2, i.e. the output will be non-empty. Additionally, it is guaranteed that p forms a non-decreasing sequence at all times.

Output

Print a real number for every request of type 2 — the probability that boy will "dominate" on that interval. Your answer will be considered correct if its absolute error does not exceed 10 - 4.

Namely: let's assume that one of your answers is a, and the corresponding answer of the jury is b. The checker program will consider your answer correct if |a - b| ≤ 10 - 4.

Example

Input

3 13
1 3
1 2
2 3
2 1 1
2 1 2
2 1 3
2 2 2
2 2 3
2 3 3
1 2 2 3
2 1 1
2 1 2
2 1 3
2 2 2
2 2 3
2 3 3


Output

0.3333333333
0.2000000000
0.1666666667
0.5000000000
0.4000000000
0.6666666667
0.3333333333
0.2500000000
0.2222222222
0.6666666667
0.5714285714
0.6666666667

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T& x) {
  x = 0;
  T fl = 1;
  char ch = 0;
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-') fl = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = (x << 1) + (x << 3) + (ch ^ 48);
  x *= fl;
}
template <typename T, typename... Args>
inline void read(T& x, Args&... args) {
  read(x);
  read(args...);
}
const int N = 100000 + 6;
struct seg {
  struct node {
    double su, mu;
  } tr[N << 2];
  void pushup(int nod) {
    tr[nod].mu = tr[(nod << 1)].mu * tr[(nod << 1 | 1)].mu;
    tr[nod].su = tr[(nod << 1)].su + tr[(nod << 1)].mu * tr[(nod << 1 | 1)].su;
  }
  void ins(int nod, int l, int r, int k, double val) {
    if (l == r) {
      tr[nod].mu = tr[nod].su = val;
      return;
    }
    int mid = (l + r) >> 1;
    if (k <= mid)
      ins((nod << 1), l, mid, k, val);
    else
      ins((nod << 1 | 1), mid + 1, r, k, val);
    pushup(nod);
  }
  double query1(int nod, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return tr[nod].mu;
    int mid = (l + r) >> 1;
    double res = 1.0;
    if (ql <= mid) res = res * query1((nod << 1), l, mid, ql, qr);
    if (qr > mid) res = res * query1((nod << 1 | 1), mid + 1, r, ql, qr);
    return res;
  }
  double query(int nod, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return tr[nod].su;
    int mid = (l + r) >> 1;
    double res = 0.0;
    if (ql <= mid) res += query((nod << 1), l, mid, ql, qr);
    if (qr > mid)
      res += query((nod << 1 | 1), mid + 1, r, ql, qr) *
             query1((nod << 1), l, mid, ql, mid);
    return res;
  }
} sgt;
double p[N], t[N];
int n, m;
int main() {
  read(n, m);
  for (int i = (1); i <= (n); i++) {
    int a, b;
    read(a, b);
    p[i] = (1.0 * a) / (1.0 * b);
    t[i] = (1.0 - p[i]) / p[i];
    sgt.ins(1, 1, n, i, t[i]);
  }
  for (int _ = (1); _ <= (m); _++) {
    int opt, x, y, z;
    read(opt);
    if (opt == 1) {
      read(x, y, z);
      p[x] = (1.0 * y) / (1.0 * z);
      t[x] = (1.0 - p[x]) / p[x];
      sgt.ins(1, 1, n, x, t[x]);
    } else {
      read(x, y);
      double res = sgt.query(1, 1, n, x, y);
      printf("%.10f\n", 1.0 / (1.0 + res));
    }
  }
  return 0;
}