import java.util.*;
import java.lang.*;
public class Cf1288A {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int t,n,d,l;
		t=sc.nextInt();
		while(t>0) {
			n=sc.nextInt();
			d=sc.nextInt();
			if((int)Math.ceil(2*Math.sqrt(d)-1)<=n)
				System.out.println("YES");
			else
				System.out.println("NO");
			t--;
		}
		sc.close();
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class codeforces_1288A {
	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new
					InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
	public static void main(String[] args) {
		FastReader ob = new FastReader();
		int t= ob.nextInt();
		for (int i1 = 0; i1 < t; i1++) {
			int n = ob.nextInt();
			int d = ob.nextInt();
			if(d<=n) {
				System.out.println("YES");
			}
			else {
				boolean flag=false;
				for(int i=1;i<=n;) {
					double d1 =d;
					double i2=i;
					double k2 = d1/(i2+1);
					double k = Math.ceil(k2);
					if(i+(int)k<=n) {
						//System.out.println(i+" "+k2+" "+k);
						System.out.println("YES");
						flag=true;
						break;
					}

					i*=2;
				}
				if(!flag) {
					System.out.println("NO");
				}
			}

		}

	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class codeforces_1288A {
	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new
					InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
	public static void main(String[] args) {
		FastReader ob = new FastReader();
		int t= ob.nextInt();
		for (int i1 = 0; i1 < t; i1++) {
			int n = ob.nextInt();
			int d = ob.nextInt();
			if(d<=n) {
				System.out.println("YES");
			}
			else {
				boolean flag=false;
				for(int i=1;i<=n;) {
					double d1 =d;
					double i2=i;
					double k2 = d1/(i2+1);
					double k = Math.ceil(k2);
					if(i+(int)k<=n) {
						//System.out.println(i+" "+k2+" "+k);
						System.out.println("YES");
						flag=true;
						break;
					}
					i++;
				}
				if(!flag) {
					System.out.println("NO");
				}
			}
		}
	}
}


import java.util.Scanner;

public class Code1
{
    static Scanner sc = new Scanner(System.in);
   public static void main(String[] args)
   {
       int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int x=(int) (Math.ceil(d/2));
           x=x+1;
           if(d<=n)
           {
               System.out.println("YES");
           }
           else if(x<=n)
           {
               System.out.println("YES");
           }
           else if(x>n)
           {
               System.out.println("NO");
           }
       }
   }
}


import java.util.Scanner;

public class CodeForces
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int x=(int) (1+Math.ceil((float)(d)/(float)(2)));
           if(d<=n)
           {
               System.out.println("YES");
           }
           else if(x<=n)
           {
               System.out.println("YES");
           }
           else if(x>n)
           {
               System.out.println("NO");
           }
       }
    }
}


import java.util.Scanner;

public class CodeForces
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
            int n=sc.nextInt(),d=sc.nextInt();
            if (n>100000) System.out.println("YES");
            else {
                if (n>=d)
                {
                    System.out.println("YES");
                    continue;
                }
                boolean found=false;
                for (int j=1;j<=n;j++){
                    if (j+(Math.ceil((double)d/(j+1)))<=n){
                        System.out.println("YES");
                        found=true;
                        break;
                    }
                }
                if (!found) {
                    System.out.println("NO");
                }
            }
        }
    }
}


import java.util.Scanner;

public class Code1
{
    static Scanner sc = new Scanner(System.in);
   public static void main(String[] args)
   {
       int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int x=(int) (1+Math.ceil(d/2));
           x=x+1;
           if(d<=n)
           {
               System.out.println("YES");
           }
           else if(x<=n)
           {
               System.out.println("YES");
           }
           else if(x>n)
           {
               System.out.println("NO");
           }
       }
   }
}


import java.util.Scanner;

public class Code1
{
    static Scanner sc = new Scanner(System.in);
   public static void main(String[] args)
   {
       int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int x=(int) (Math.ceil(d/2));
           if(d<=n)
           {
               System.out.println("YES");
           }
           else if(x<=n)
           {
               System.out.println("YES");
           }
           else if(x>n)
           {
               System.out.println("NO");
           }
       }
   }
}


import java.util.Scanner;

public class Code1
{
    static Scanner sc = new Scanner(System.in);
   public static void main(String[] args)
   {
       int t=sc.nextInt();
       for(int i=0;i<t;i++)
       {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int x=(int) (1+Math.ceil(d/2));
           if(d<=n)
           {
               System.out.println("YES");
           }
           else if(x<=n)
           {
               System.out.println("YES");
           }
           else if(x>n)
           {
               System.out.println("NO");
           }
       }
   }
}


import java.util.*;

import static java.lang.System.out;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main
{
	static final long mod = (int)1e9+7;
	static final long M = (int)1e9+7;

	static class Reader
	{
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public Reader()
		{
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader(String file_name) throws IOException
		{
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String next() throws IOException
		{
			byte[] buf = new byte[64]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1)
			{
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException
		{
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
			{
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}
		int[] readArray(int n) throws IOException {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}

		public long nextLong() throws IOException
		{
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException
		{
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');

			if (c == '.')
			{
				while ((c = read()) >= '0' && c <= '9')
				{
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException
		{
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException
		{
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException
		{
			if (din == null)
				return;
			din.close();
		}

	}

	public static int digitSum(int n)
	{
		int sum =0;
		while(n > 0)
		{
			int last = n%10;
			sum+=last;
			n/=10;
		}
		return sum;
	}

	public static boolean isPrime(int n) {
		for(int i = 2;i*i<=n;i++)
		{
			if(n%i == 0)
			{
				return false;
			}
		}
		return true;
	}

	public static int gcd(int a, int b)
	{
		if(b == 0)
		 return a;

		else
		return gcd(b,a%b);
	}

	public static int traverser(int nums[], int n, int k)
    {
        int product = 1;

        if (nums[n - 1] == 0 && k % 2 != 0)
            return 0;

        if (nums[n - 1] <= 0 && k % 2 != 0) {
            for (int i = n - 1; i >= n - k; i--)
                product *= nums[i];
            return product;
        }

        int i = 0;

        int j = n - 1;
        if (k % 2 != 0) {
            product *= nums[j];
            j--;
            k--;
        }

        k >>= 1;

        for (int l = 0; l < k; l++) {
            int left_product = nums[i] * nums[i + 1];

            int right_product = nums[j] * nums[j - 1];

            if (left_product > right_product) {
                product *= left_product;
                i += 2;
            }
            else {
                product *= right_product;
                j -= 2;
            }
        }

        return product;
    }

	public static int[] computePrefix(int arr[], int n)
	{
		int[] prefix = new int[n];
		prefix[0] = arr[0];
		for(int i = 1;i<n;i++)
		{
			prefix[i] = prefix[i-1]+arr[i];
		}

		return prefix;
	}

	public static int lcm(int a, int b)
	{
		return (a*b)/gcd(a,b);
	}

	public static int phi(int n)  //euler totient function
    {
        int result = 1;
        for (int i = 2; i < n; i++)
            if (gcd(i, n) == 1)
                result++;
        return result;
    }

	public static void main(String[] args) throws IOException
	{
		Reader sc=new Reader();

		int t = sc.nextInt();

		while(t-- > 0)
		{
			int n = sc.nextInt();
			int d = sc.nextInt();

			int i, calc = (int)(Math.sqrt(d) + 10);
			for(i = 0;i<calc;i++)
			{
				if(i+(d+i) / (i+1) <= n)
				{
					break;
				}
			}
			if(i < calc)
			{
				System.out.println("YES");
			}
			else {
				System.out.println("NO");
			}
		}

	}

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskA {
        public void solve(int testNumber, Scanner in, PrintWriter out) {
            int t = in.nextInt();
            while (t-- > 0) {
                long n = in.nextLong();
                long d = in.nextLong();
                long val = (n - 1) / 2;
                if ((n - val) * (val + 1) >= d)
                    out.println("YES");
                else
                    out.println("NO");
            }
        }

    }
}


/*input
3
1 1
4 5
5 11

*/

import java.math.*;
import java.io.*;
import java.util.*;
public class Main
{
    static class Reader
    {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;
public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }
public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do
            {
                ret = ret * 10 + c - '0';
            }  while ((c = read()) >= '0' && c <= '9');
if (neg)
                return -ret;
            return ret;
        }
public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }
public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
if (c == '.')
            {
                while ((c = read()) >= '0' && c <= '9')
                {
                    ret += (c - '0') / (div *= 10);
                }
            }
if (neg)
                return -ret;
            return ret;
        }
private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }
private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }
public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }

    static Reader sc=new Reader();
    static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));

static int max=0;

    public static void main(String args[])throws IOException
    {
        /*
         * For integer input: int n=inputInt();
         * For long input: long n=inputLong();
         * For double input: double n=inputDouble();
         * For String input: String s=inputString();
         * Logic goes here
         * For printing without space: print(a+""); where a is a variable of any datatype
         * For printing with space: printSp(a+""); where a is a variable of any datatype
         * For printing with new line: println(a+""); where a is a variable of any datatype
            Scanner in = new Scanner(System.in);
        //all four
         int[] dr = { 1, 0, -1, 0 };
         int[] dc = { 0, 1, 0, -1 };
         println("Case #"+k+": "+1+"");//Google

         */

         int t= inputInt();

         while(t-->0)
         {
        	int n=inputInt(),d=inputInt();

        	int i=0,j=n,flag=0;

        	while(i<j)
        	{
        			int mid=i+(j-i)/2;

        			if((int)Math.ceil(d/((mid+1)*1.0))+mid<=n)
        			{
        				flag=1;
        				break;
        			}
        			else
        			{
        				j=mid;
        			}

       	 	}

       	 	if(flag==1)
       	 	println("YES");
       	 	else
       	 	println("NO") ;
       }

bw.flush();
  bw.close();

}

static void dfs(int src,int par,List<List<Integer>> ls,boolean visit[])
    {

        if(visit[src])
            return;
        visit[src]=true;

        Iterator<Integer> ite = ls.get(src).listIterator();

        while(ite.hasNext())
        {
            int x=ite.next();

            if(!visit[x])
            {

                dfs(x,par,ls,visit);
            }
        }

    }

        public static long pow(long a,long b)
        {
            long result=1;

            while(b>0)
            {
                if(b%2==1) result*=a;
                a*=a;
                b/=2;
            }
            return result;
        }

        public static long nCr(long n, long r)
        {
            long ans=1;
            if(r>n-r)
            {
                r=n-r;
            }
            for(long i=1;i<=r;i++)
            {
                ans*=(n-i+1);
                ans/=i;
            }
            return ans;
        }
        public static long modulo(long x,long N)
        {
            return (x % N + N) %N;
        }
        public static long lcm(long a,long b)
        {
            return a / gcd(a, b) * b;
        }
        public static long gcd(long a,long b)
        {
            if(b==0)
                return a;
            return gcd(b,a%b);
        }

     public static int inputInt()throws IOException
    {
        return sc.nextInt();
    }
    public static long inputLong()throws IOException
    {
        return sc.nextLong();
    }
    public static double inputDouble()throws IOException
    {
        return sc.nextDouble();
    }
    public static String inputString()throws IOException
    {
        return sc.readLine();
    }
    public static void print(String a)throws IOException
    {
        bw.write(a);
    }
    public static void printSp(String a)throws IOException
    {
        bw.write(a+" ");
    }
    public static void println(String a)throws IOException
    {
        bw.write(a+"\n");
    }
}


import java.util.Scanner;

/**
 *
 * @author DELL
 */
public class Codechef {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++)
        {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int flag=0;
           if(n>=d)
           {
               System.out.println("YES");
           }
           else
           {
               for(int j=0;j<d;j++)
               {
                   if(j>n)
                       break;
                   float y=(float)d/(j+1);
                   Math.ceil(y);
                                     if(y+j<=n)
                   {
                       flag=1;
                       System.out.println("YES");
                       break;
                   }

               }
               if(flag==0)
                   System.out.println("NO");
           }
}
}
}


import java.util.Scanner;

/**
 *
 * @author DELL
 */
public class Codechef {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++)
        {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int flag=0;
           if(n>=d)
           {
               System.out.println("YES");
           }
           else
           {
               for(int j=0;j<d;j++)
               {
                   float y=(float)d/(j+1);
                   Math.ceil(y);
                                     if(y+j<=n)
                   {
                       flag=1;
                       System.out.println("YES");
                       break;
                   }

               }
               if(flag==0)
                   System.out.println("NO");
           }
}
}
}


import java.util.Scanner;

/**
 *
 * @author DELL
 */
public class Codechef {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++)
        {
           int n=sc.nextInt();
           long d=sc.nextInt();
           int flag=0;
           if(n>=d)
           {
               System.out.println("YES");
           }
           else
           {
               for(int j=0;j<=(int)Math.sqrt(d);j++)
               {
                   double y=(double)d/(j+1);
                   y=y+j;
                   y=Math.ceil(y);
                                     if(y<=n)
                   {
                       flag=1;
                       System.out.println("YES");
                       break;
                   }

               }
               if(flag==0)
                   System.out.println("NO");
           }
}
}
}


import java.util.Scanner;

/**
 *
 * @author DELL
 */
public class Codechef {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++)
        {
           int n=sc.nextInt();
           int d=sc.nextInt();
           int flag=0;
           if(n>=d)
           {
               System.out.println("YES");
               continue;
           }
           else
           {
               for(int j=1;j<d;j++)
               {
                   int y=d/(j+1);
                   y=y+1;
                   if(y+j<=n)
                   {
                       flag=1;
                       System.out.println("YES");
                       break;
                   }

               }
               if(flag==0)
                   System.out.println("NO");
           }
}
}
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
typedef pair<double,double> SgTreeDataType;
struct treenode
{
  int L , R  ;
  SgTreeDataType A;
  void updata(SgTreeDataType v)
  {
      A=v;
  }
};
pair<double,double>tmp=make_pair(1.0,0);
treenode tree[maxn*4];

inline void push_up(int o)
{
    tree[o].A.first = tree[o*2].A.first*tree[o*2+1].A.first;
    tree[o].A.second = tree[o*2].A.second + tree[o*2+1].A.second * tree[o*2].A.first;
}

inline void build_tree(int L , int R , int o)
{
    tree[o].L = L , tree[o].R = R;
    if (R > L)
    {
        int mid = (L+R) >> 1;
        build_tree(L,mid,o*2);
        build_tree(mid+1,R,o*2+1);
    }
}

inline void update(int QL,int QR,SgTreeDataType v,int o)
{
    int L = tree[o].L , R = tree[o].R;
    if (QL <= L && R <= QR) tree[o].updata(v);
    else
    {
        int mid = (L+R)>>1;
        if (QL <= mid) update(QL,QR,v,o*2);
        if (QR >  mid) update(QL,QR,v,o*2+1);
        push_up(o);
    }
}

inline SgTreeDataType query(int QL,int QR,int o)
{
    int L = tree[o].L , R = tree[o].R;
    if (QL <= L && R <= QR) return tree[o].A;
    else
    {
        int mid = (L+R)>>1;
        SgTreeDataType AA=tmp,BB=tmp,CC;
        if (QL <= mid) AA = query(QL,QR,2*o);
        if (QR > mid) BB = query(QL,QR,2*o+1);
        push_up(o);
        CC.first=AA.first*BB.first;
        CC.second=AA.second+BB.second*AA.first;
        return CC;
    }
}

int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    build_tree(1,n,1);
    for(int i=1;i<=n;i++)
    {
        double a,b;
        cin>>a>>b;
        double p = a/b;
        update(i,i,make_pair((1.0-p)/p,(1.0-p)/p),1);
    }
    for(int i=1;i<=q;i++)
    {
        int op,a,b,c;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d%d",&a,&b,&c);
            double p = 1.0*b/(1.0*c);
            pair<double,double>D=make_pair((1-p)/p,(1-p)/p);
            update(a,a,D,1);
        }
        else
        {
            scanf("%d%d",&a,&b);
            double p = query(a,b,1).second;
            if(p<1e20)printf("%.12f\n",1.0/(1.0+p));
            else printf("0.000000000000\n");
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<double, double> pdd;
#define lson l, m, rt<<1
#define rson m + 1, r, rt<<1|1
#define ll long long
#define mp make_pair
#define fir first
#define se second

const int maxn = 1e5 + 10;
pdd A[maxn<<2];

void PushUp(int rt)
{
	A[rt].fir = A[rt<<1].fir * A[rt<<1|1].fir;
	A[rt].se = A[rt<<1].se + A[rt<<1|1].se * A[rt<<1].fir;
}

void build(int l, int r, int rt)
{
	if(l == r) {
		A[rt].fir = 1.0;
		A[rt].se = 0;
		return;
	}
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
}

void update(int p, pdd tmp, int l, int r, int rt)
{
	if(l == r) {
		A[rt] = tmp;
		return;
	}
	int m = (l + r) >> 1;
	if(p <= m) update(p, tmp, lson);
	else update(p, tmp, rson);
	PushUp(rt);
}

pdd query(int L, int R, int l, int r, int rt)
{
	if(L <= l && r <= R) {
		return A[rt];
	}
	int m = (l + r) >> 1;
	pdd AA = {1.0, 0}, BB = {1.0, 0}, CC;
	if(L <= m) AA = query(L, R, lson);
	if(R > m) BB = query(L, R, rson);
	//PushUp(rt);
	CC.fir = AA.fir * BB.fir;
	CC.se = AA.se + BB.se * AA.fir;
	return CC;
}

int main()
{
	int n, q;
	scanf("%d %d", &n, &q);
	build(1, n, 1);
	for(int i = 1; i <= n; i++) {
		double a, b;
		scanf("%lf %lf", &a, &b);
		double p = a / b;
		double u = (1 - p) / p;
		update(i, mp(u, u), 1, n, 1);
	}
	for(int i = 1; i <= q; i++) {
		int op, a, b, c;
		scanf("%d", &op);
		if(op == 1) {
			scanf("%d %d %d", &a, &b, &c);
			double p = 1.0 * b / (1.0 * c);
			double u = (1 - p) / p;
			pair<double, double> D = mp(u, u);
			update(a, D, 1, n, 1);
		}
		else {
			scanf("%d %d", &a, &b);
			double p = query(a, b, 1, n, 1).se;
			printf("%.10f\n", 1.0 / (1.0 + p));
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<double, double> pdd;
#define lson l, m, rt<<1
#define rson m + 1, r, rt<<1|1
#define ll long long
#define mp make_pair
#define fir first
#define se second

const int maxn = 1e5 + 10;
pdd A[maxn<<2];

void PushUp(int rt)
{
	A[rt].fir = A[rt<<1].fir * A[rt<<1|1].fir;
	A[rt].se = A[rt<<1].se + A[rt<<1|1].se * A[rt<<1].fir;
}

void build(int l, int r, int rt)
{
	if(l == r) {
		A[rt].fir = 1.0;
		A[rt].se = 0;
		return;
	}
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
}

void update(int p, pdd tmp, int l, int r, int rt)
{
	if(l == r) {
		A[rt] = tmp;
		return;
	}
	int m = (l + r) >> 1;
	if(p <= m) update(p, tmp, lson);
	else update(p, tmp, rson);
	PushUp(rt);
}

pdd query(int L, int R, int l, int r, int rt)
{
	if(L <= l && r <= R) {
		return A[rt];
	}
	int m = (l + r) >> 1;
	pdd AA = {1.0, 0}, BB = {1.0, 0}, CC;
	if(L <= m) AA = query(L, R, lson);
	if(R > m) BB = query(L, R, rson);
	//PushUp(rt);
	CC.fir = AA.fir * BB.fir;
	CC.se = AA.se + BB.se * AA.fir;
	return CC;
}

int main()
{
	int n, q;
	scanf("%d %d", &n, &q);
	build(1, n, 1);
	for(int i = 1; i <= n; i++) {
		double a, b;
		scanf("%lf %lf", &a, &b);
		double p = a / b;
		double u = (1 - p) / p;
		update(i, mp(u, u), 1, n, 1);
	}
	for(int i = 1; i <= q; i++) {
		int op, a, b, c;
		scanf("%d", &op);
		if(op == 1) {
			scanf("%d %d %d", &a, &b, &c);
			double p = 1.0 * b / (1.0 * c);
			double u = (1 - p) / p;
			pair<double, double> D = mp(u, u);
			update(a, D, 1, n, 1);
		}
		else {
			scanf("%d %d", &a, &b);
			double p = query(a, b, 1, n, 1).se;
			double ans = 1.0 / (1.0 + p);
			if(ans >= 0) printf("%.10f\n", 1.0 / (1.0 + p));
			else printf("0\n");
		}
	}
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		double x,y;
		cin>>x>>y;
		f[i]=x/y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=1.0*(double)y/(1.0*(double)z);
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a*q1[i];
			}
			double ans=1.0/(1.0+b);
			if (ans<1e-10) printf("%.10lf\n",0.0);
			else printf("%.10lf\n",ans);
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		double x,y;
		cin>>x>>y;
		f[i]=x/y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=1.0*(double)y/(1.0*(double)z);
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a*q1[i];
			}
			printf("%.10lf\n",1.0/(1.0+b));
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		double x,y;
		cin>>x>>y;
		f[i]=x/y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=1.0*(double)y/(1.0*(double)z);
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a*q1[i];
			}
			if (b>1e15) printf("%.10lf\n",0.0);
			else printf("%.10lf\n",1.0/(1.0+b));
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		double x,y;
		cin>>x>>y;
		f[i]=x/y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=1.0*(double)y/(1.0*(double)z);
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a*q1[i];
			}
			if (b<1e20) printf("%.10lf\n",1.0/(1.0+b));
			else printf("%.10lf\n",0.0);
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
		update(k);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		f[i]=(double)x/(double)y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=(double)y/(double)z;
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a+q1[i];
			}
			printf("%.10lf\n",1.0/(1.0+b));
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>

using namespace std;
double f[110000];
int n,m;
vector<double> q1,q2;
struct Seg
{
	struct data{
   		int l,r;
   		double a,b;
	}tr[2000001];
	void update(int k)
	{
		tr[k].a=tr[k<<1].a*tr[k<<1|1].a;
		tr[k].b=tr[k<<1].b+tr[k<<1].a*tr[k<<1|1].b;
	}
	void build(int k,int s,int t)
	{
    	tr[k].l=s;tr[k].r=t;
    	if(s==t)
		{
			tr[k].a=tr[k].b=f[s];
			return;
		}
    	int mid=(s+t)>>1;
    	build(k<<1,s,mid);
    	build(k<<1|1,mid+1,t);
    	update(k);
	}
	void pchange(int k,int a)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==r)
		{
			tr[k].a=tr[k].b=f[l];
			return;
		}
		int mid=(l+r)>>1;
		if (a<=mid) pchange(k<<1,a);
		else pchange(k<<1|1,a);
		update(k);
	}
	void lask(int k,int a,int b)
	{
		int l=tr[k].l,r=tr[k].r;
		if (l==a&&r==b)
		{
			q1.push_back(tr[k].a);
			q2.push_back(tr[k].b);
			return;
		}
		int mid=(l+r)>>1;
		if (b<=mid) lask(k<<1,a,b);
		else if (a>mid) lask(k<<1|1,a,b);
		else lask(k<<1,a,mid),lask(k<<1|1,mid+1,b);
	}
}T;
int main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		double x,y;
		cin>>x>>y;
		f[i]=x/y;
		f[i]=(1.0-f[i])/f[i];
	}
	T.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int op,x,y,z;
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>z;
			f[x]=1.0*(double)y/(1.0*(double)z);
			f[x]=(1.0-f[x])/f[x];
			T.pchange(1,x);
		}
		else
		{
			cin>>x>>y;
			q1.clear(),q2.clear();
			T.lask(1,x,y);
			double a=q1[0],b=q2[0];
			for (int i=1;i<q1.size();i++)
			{
				b=b+a*q2[i];
				a=a*q1[i];
			}
			double ans=1.0/(1.0+b);
			if (ans>1e10) printf("%.10lf\n",0.0);
			else printf("%.10lf\n",ans);
		}
	}
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int SN = 1 << 18;
int n , q;
int a[N];
int b[N];
int type , l , r;
typedef pair < pair < long double , long double > , pair < long double , long double > > mat;
typedef pair < long double , long double > vec;
mat segtree[SN];
mat operator * (mat a , mat b){
    return mat{{a.first.first * b.first.first + a.first.second * b.second.first , a.first.first * b.first.second + a.first.second * b.second.second} , {a.second.first * b.first.first + a.second.second * b.second.first , a.second.first * b.first.second + a.second.second * b.second.second}};
}
vec operator * (mat a , vec b){
    return vec{a.first.first * b.first + a.first.second * b.second , a.second.first * b.first + a.second.second * b.second};
}
void build(int l , int r , int node){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        build(l , mid , node + node);
        build(mid + 1 , r , node + node + 1);
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
void update(int l , int r , int node , int idx){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        if(idx <= mid){
            update(l , mid , node + node , idx);
        }
        else{
            update(mid + 1 , r , node + node + 1 , idx);
        }
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
mat query(int l , int r , int node , int ql , int qr){
    if(l > qr || r < ql || ql > qr){
        return mat{{1 , 0} , {0 , 1}};
    }
    if(l >= ql && r <= qr){
        return segtree[node];
    }
    int mid = l + r >> 1;
    return query(l , mid , node + node , ql , qr) * query(mid + 1 , r , node + node + 1 , ql , qr);
}
int main(){
    scanf("%d %d" , &n , &q);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%d %d" , a + i , b + i);
    }
    build(1 , n , 1);
    while(q--){
        scanf("%d" , &type);
        if(type == 1){
            int i;
            scanf("%d" , &i);
            scanf("%d %d" , a + i , b + i);
            update(1 , n , 1 , i);
        }
        else{
            scanf("%d %d" , &l , &r);
            vec ans = query(1 , n , 1 , l , r - 1) * vec{a[r] , b[r]};
            printf("%.6llf\n" , ans.first / ans.second);
        }
    }
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int SN = 1 << 18;
int n , q;
int a[N];
int b[N];
int type , l , r;
typedef pair < pair < double , double > , pair < double , double > > mat;
typedef pair < double , double > vec;
mat segtree[SN];
mat operator * (mat a , mat b){
    return mat{{a.first.first * b.first.first + a.first.second * b.second.first , a.first.first * b.first.second + a.first.second * b.second.second} , {a.second.first * b.first.first + a.second.second * b.second.first , a.second.first * b.first.second + a.second.second * b.second.second}};
}
vec operator * (mat a , vec b){
    return vec{a.first.first * b.first + a.first.second * b.second , a.second.first * b.first + a.second.second * b.second};
}
void build(int l , int r , int node){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        build(l , mid , node + node);
        build(mid + 1 , r , node + node + 1);
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
void update(int l , int r , int node , int idx){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        if(idx <= mid){
            update(l , mid , node + node , idx);
        }
        else{
            update(mid + 1 , r , node + node + 1 , idx);
        }
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
mat query(int l , int r , int node , int ql , int qr){
    if(l > qr || r < ql || ql > qr){
        return mat{{1 , 0} , {0 , 1}};
    }
    if(l >= ql && r <= qr){
        return segtree[node];
    }
    int mid = l + r >> 1;
    return query(l , mid , node + node , ql , qr) * query(mid + 1 , r , node + node + 1 , ql , qr);
}
int main(){
    scanf("%d %d" , &n , &q);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%d %d" , a + i , b + i);
    }
    build(1 , n , 1);
    while(q--){
        scanf("%d" , &type);
        if(type == 1){
            int i;
            scanf("%d" , &i);
            scanf("%d %d" , a + i , b + i);
            update(1 , n , 1 , i);
        }
        else{
            scanf("%d %d" , &l , &r);
            vec ans = query(1 , n , 1 , l , r - 1) * vec{a[r] , b[r]};
            printf("%.6lf\n" , ans.first / ans.second);
        }
    }
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int SN = 1 << 18;
int n , q;
int a[N];
int b[N];
int type , l , r;
typedef pair < pair < long double , long double > , pair < long double , long double > > mat;
typedef pair < long double , long double > vec;
mat segtree[SN];
mat operator * (mat a , mat b){
    return mat{{a.first.first * b.first.first + a.first.second * b.second.first , a.first.first * b.first.second + a.first.second * b.second.second} , {a.second.first * b.first.first + a.second.second * b.second.first , a.second.first * b.first.second + a.second.second * b.second.second}};
}
vec operator * (mat a , vec b){
    return vec{a.first.first * b.first + a.first.second * b.second , a.second.first * b.first + a.second.second * b.second};
}
void build(int l , int r , int node){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        build(l , mid , node + node);
        build(mid + 1 , r , node + node + 1);
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
void update(int l , int r , int node , int idx){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        if(idx <= mid){
            update(l , mid , node + node , idx);
        }
        else{
            update(mid + 1 , r , node + node + 1 , idx);
        }
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
mat query(int l , int r , int node , int ql , int qr){
    if(l > qr || r < ql || ql > qr){
        return mat{{1 , 0} , {0 , 1}};
    }
    if(l >= ql && r <= qr){
        return segtree[node];
    }
    int mid = l + r >> 1;
    return query(l , mid , node + node , ql , qr) * query(mid + 1 , r , node + node + 1 , ql , qr);
}
int main(){
    scanf("%d %d" , &n , &q);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%d %d" , a + i , b + i);
    }
    build(1 , n , 1);
    while(q--){
        scanf("%d" , &type);
        if(type == 1){
            int i;
            scanf("%d" , &i);
            scanf("%d %d" , a + i , b + i);
            update(1 , n , 1 , i);
        }
        else{
            scanf("%d %d" , &l , &r);
            vec ans = query(1 , n , 1 , l , r - 1) * vec{a[r] , b[r]};
            printf("%.6lf\n" , double(ans.first / ans.second));
        }
    }
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int SN = 1 << 18;
int n , q;
int a[N];
int b[N];
int type , l , r;
double seg1[SN];
double seg2[SN];
void build(int l , int r , int node){
    if(l == r){
        seg1[node] = 1.0 * a[l] / b[r];
        seg2[node] = (l > 1) ? 1.0 * a[l - 1] * (b[r] - a[r]) / (b[l] * b[l - 1]) : 0;
    }
    else{
        int mid = l + r >> 1;
        build(l , mid , node + node);
        build(mid + 1 , r , node + node + 1);
        seg1[node] = seg1[node + node] * seg1[node + node + 1];
        seg2[node] = seg2[node + node] + seg2[node + node + 1];
    }
}
void update(int l , int r , int node , int idx){
    if(l == r){
        seg1[node] = 1.0 * a[l] / b[r];
        seg2[node] = (l > 1) ? 1.0 * a[l - 1] * (b[r] - a[r]) / (b[l] * b[l - 1]) : 0;
    }
    else{
        int mid = l + r >> 1;
        if(idx <= mid){
            update(l , mid , node + node , idx);
        }
        else{
            update(mid + 1 , r , node + node + 1 , idx);
        }
        seg1[node] = seg1[node + node] * seg1[node + node + 1];
        seg2[node] = seg2[node + node] + seg2[node + node + 1];
    }
}
pair < double , double > query(int l , int r , int node , int ql , int qr){
    if(l > qr || r < ql || ql > qr){
        return make_pair(1 , 0);
    }
    if(l >= ql && r <= qr){
        return make_pair(seg1[node] , seg2[node]);
    }
    int mid = l + r >> 1;
    auto lft = query(l , mid , node + node , ql , qr);
    auto rgt = query(mid + 1 , r , node + node + 1 , ql , qr);
    return make_pair(lft.first * rgt.first , lft.second + rgt.second);
}
int main(){
    scanf("%d %d" , &n , &q);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%d %d" , a + i , b + i);
    }
    build(1 , n , 1);
    while(q--){
        scanf("%d" , &type);
        if(type == 1){
            int i;
            scanf("%d" , &i);
            scanf("%d %d" , a + i , b + i);
            update(1 , n , 1 , i);
            if(i < n){
                update(1 , n , 1 , i + 1);
            }
        }
        else{
            scanf("%d %d" , &l , &r);
            auto it = query(1 , n , 1 , l + 1 , r);
            printf("%.6lf\n" , (it.first * a[l]) / ((1 - it.second) * b[l]));
        }
    }
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int SN = 1 << 18;
int n , q;
int a[N];
int b[N];
int type , l , r;
typedef pair < pair < double , double > , pair < double , double > > mat;
typedef pair < double , double > vec;
mat segtree[SN];
mat unrekt(mat res){
    if(max(max(res.first.first , res.first.second) , max(res.second.first , res.second.second)) > 1e9){
        res.first.first /= 1e9;
        res.first.second /= 1e9;
        res.second.first /= 1e9;
        res.second.second /= 1e9;
    }
    return res;
}
mat operator * (mat a , mat b){
    return unrekt(mat{{a.first.first * b.first.first + a.first.second * b.second.first , a.first.first * b.first.second + a.first.second * b.second.second} , {a.second.first * b.first.first + a.second.second * b.second.first , a.second.first * b.first.second + a.second.second * b.second.second}});
}
vec operator * (mat a , vec b){
    return vec{a.first.first * b.first + a.first.second * b.second , a.second.first * b.first + a.second.second * b.second};
}
void build(int l , int r , int node){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        build(l , mid , node + node);
        build(mid + 1 , r , node + node + 1);
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
void update(int l , int r , int node , int idx){
    if(l == r){
        segtree[node] = mat{{1 , 0} , {1 , 1.0 * (b[l] - a[r]) / a[l]}};
    }
    else{
        int mid = l + r >> 1;
        if(idx <= mid){
            update(l , mid , node + node , idx);
        }
        else{
            update(mid + 1 , r , node + node + 1 , idx);
        }
        segtree[node] = segtree[node + node] * segtree[node + node + 1];
    }
}
mat query(int l , int r , int node , int ql , int qr){
    if(l > qr || r < ql || ql > qr){
        return mat{{1 , 0} , {0 , 1}};
    }
    if(l >= ql && r <= qr){
        return segtree[node];
    }
    int mid = l + r >> 1;
    return query(l , mid , node + node , ql , qr) * query(mid + 1 , r , node + node + 1 , ql , qr);
}
int main(){
    scanf("%d %d" , &n , &q);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%d %d" , a + i , b + i);
    }
    build(1 , n , 1);
    while(q--){
        scanf("%d" , &type);
        if(type == 1){
            int i;
            scanf("%d" , &i);
            scanf("%d %d" , a + i , b + i);
            update(1 , n , 1 , i);
        }
        else{
            scanf("%d %d" , &l , &r);
            vec ans = query(1 , n , 1 , l , r - 1) * vec{a[r] , b[r]};
            printf("%.6lf\n" , ans.first / ans.second);
        }
    }
}


#include<iostream>
#include<cstdio>
using namespace std;

typedef pair<double,double>Pdd;
Pdd a[1<<18];
Pdd Merge(Pdd x,Pdd y)
{
    double l1=x.first;
    double r1=x.second;
    double l2=y.first;
    double r2=y.second;
    double l=(l1*l2)/(1-(1-l2)*r1);
    double r=r2+((1-r2)*l2*r1)/(1-(1-l2)*r1);
    return {l,r};
}

void Build(int o,int l,int r)
{
    if(l==r)
    {
        double x,y;
        scanf("%lf %lf",&x,&y);
        a[o]={x/y,x/y};
        return ;
    }
    int mid=(l+r)/2;
    Build(o<<1,l,mid);
    Build(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}
Pdd V;
int p;
void Update(int o,int l,int r)
{
    if(l==r){
        a[o]=V;
        return;
    }
    int mid=(l+r)/2;
    if(p<=mid) Update(o<<1,l,mid);
    else Update(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}

int L,R;
Pdd Query(int o,int l,int r)
{
    if(L<=l&&R>=r) return a[o];
    int mid=(l+r)/2;
    if(R<=mid) return Query(o<<1,l,mid);
    else if(L>mid) return Query(o<<1|1,mid+1,r);
    else return Merge(Query(o<<1,l,mid),Query(o<<1|1,mid+1,r));
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    Build(1,1,n);
    int tag;
    for(int i=0;i<m;i++)
    {
        scanf("%d",&tag);
        double x,y;
        if(tag==1)
        {
            scanf("%d%d%d",&p,&x,&y);
            V={x/y,x/y};
            Update(1,1,n);

        }
        else{
            scanf("%d%d",&L,&R);
            printf("%.10f\n",Query(1,1,n).first);
        }
    }
    return 0;

}


#include<iostream>
#include<cstdio>
using namespace std;

typedef pair<double,double>Pdd;
Pdd a[1<<18];
Pdd Merge(Pdd x,Pdd y)
{
    double l1=x.first;
    double r1=x.second;
    double l2=y.first;
    double r2=y.second;
    double l=(l1*l2)/(1-(1-l2)*r1);
    double r=r2+((1-r2)*l2*r1)/(1-(1-l2)*r1);
    return {l,r};
}

void Build(int o,int l,int r)
{
    if(l==r)
    {
        double x,y;
        scanf("%lf %lf",&x,&y);
        a[o]={x/y,x/y};
        return ;
    }
    int mid=(l+r)/2;
    Build(o<<1,l,mid);
    Build(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}
Pdd V;
int p;
void Update(int o,int l,int r)
{
    if(l==r){
        a[o]=V;
        return;
    }
    int mid=(l+r)/2;
    if(p<=mid) Update(o<<1,l,mid);
    else Update(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}

int L,R;
Pdd Query(int o,int l,int r)
{
    if(L<=l&&R>=r) return a[o];
    int mid=(l+r)/2;
    if(R<=mid) return Query(o<<1,l,mid);
    else if(L>mid) return Query(o<<1|1,mid+1,r);
    else return Merge(Query(o<<1,l,mid),Query(o<<1|1,mid+1,r));
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    Build(1,1,n);
    int tag;
    for(int i=0;i<m;i++)
    {
        scanf("%d",&tag);
        double x,y;
        if(tag==1)
        {
            scanf("%d%lf%lf",&p,&x,&y);
            V={x/y,x/y};
            Update(1,1,n);

        }
        else{
            scanf("%d%d",&L,&R);
            printf("%.10f\n",Query(1,1,n).first);
        }
    }
    return 0;

}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;

typedef pair <double,double> PD;
int n,q;
PD a[1<<18];
PD merge(PD x,PD y)
{
    double l1,l2,r1,r2;
    l1=x.first;
    r1=x.second;
    l2=y.first;
    r2=y.second;
    double l = (l1 * l2) / (1 - (1 - l2) * r1);
    double r = r2 + ((1 - r2) * r1 * l2) / (1 - (1 - l2) * r1);
    return {l,r};
}
void build(int o,int l,int r)
{
    if(r==l)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        a[o]={x/y,x/y};//cout<<a[o].first;
        return ;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    a[o]=merge(a[o<<1],a[o<<1|1]);//cout<<a[o].first<<endl;
}
PD V;
int P;
void change(int o,int l,int r)
{
    if(l==r)
    {
        a[o]=V;
        return;
    }
    int mid=(l+r)>>1;
    if(P>mid)
        change(o<<1|1,mid+1,r);
    else
        change(o<<1,l,mid);
    a[o]=merge(a[o<<1],a[o<<1|1]);
}
int L,R;
PD question(int o,int l,int r)
{
    if(l>=L&&r<=R)
        return a[o];
    int mid=(l+r)>>1;
    if(mid>=R)
        return question(o<<1,l,mid);
    else if(mid<L)
        return question(o<<1|1,mid+1,r);
    else
        return merge(question(o<<1,l,mid),question(o<<1|1,mid+1,r));
}
int main()
{
    while(~scanf("%d%d",&n,&q))
    {
        build(1,1,n);
        while(q--)
        {
            int point;
            scanf("%d",&point);
            if(point==1)
            {
                double x,y;
                scanf("%d%lf%lf",&P,&x,&y);
                V={x/y,x/y};
                change(1,1,n);
            }
            else
            {
                scanf("%d%d",&L,&R);
                printf("%.10f\n",question(1,1,n).first);
            }
        }
    }
}


#include<iostream>
#include<cstdio>
using namespace std;

typedef pair<double,double>Pdd;
Pdd a[1<<18];
Pdd Merge(Pdd x,Pdd y)
{
    double l1=x.first;
    double r1=x.second;
    double l2=y.first;
    double r2=y.second;
    double l=(l1*l2)/(1-(1-l2)*r1);
    double r=r2+((1-r2)*l2*r1)/(1-(1-l2)*r1);
    return {l,r};
}

void Build(int o,int l,int r)
{
    if(l==r)
    {
        double x,y;
        scanf("%lf %lf",&x,&y);
        a[o]={x/y,x/y};
        return ;
    }
    int mid=(l+r)/2;
    Build(o<<1,l,mid);
    Build(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}
Pdd V;
int p;
void Update(int o,int l,int r)
{
    if(l==r){
        a[o]=V;
        return;
    }
    int mid=(l+r)/2;
    if(p<=mid) Update(o<<1,l,mid);
    else Update(o<<1|1,mid+1,r);
    a[o]=Merge(a[o<<1],a[o<<1|1]);
}

int L,R;
Pdd Query(int o,int l,int r)
{
    if(L<=l&&R>=r) return a[o];
    int mid=(l+r)/2;
    if(R<=mid) return Query(o<<1,l,mid);
    else if(L>mid) return Query(o<<1|1,mid+1,r);
    else return Merge(Query(o<<1,l,mid),Query(o<<1|1,mid+1,r));
}

int main()
{
    int n,m;
    cin>>n>>m;
    Build(1,1,n);
    int tag;
    for(int i=0;i<m;i++)
    {
        cin>>tag;
        double x,y;
        if(tag==1)
        {
            cin>>p>>x>>y;
            V={x/y,x/y};
            Update(1,1,n);

        }
        else{
            cin>>L>>R;
            printf("%.10f\n",Query(1,1,n).first);
        }
    }
    return 0;

}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;

typedef pair <double,double> PD;
int n,q;
PD a[1<<18];
PD merge(PD x,PD y)
{
    double l1,l2,r1,r2;
    l1=x.first;
    r1=x.second;
    l2=y.first;
    r2=y.second;
    double l = (l1 * l2) / (1 - (1 - l2) * r1);
    double r = r2 + ((1 - r2) * r1 * l2) / (1 - (1 - l2) * r1);
    return {l,r};
}
void build(int o,int l,int r)
{
    if(r==l)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        a[o]={x/y,x/y};//cout<<a[o].first;
        return ;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    a[o]=merge(a[o<<1],a[o<<1|1]);cout<<a[o].first<<endl;
}
PD V;
int P;
void change(int o,int l,int r)
{
    if(l==r)
    {
        a[o]=V;
        return;
    }
    int mid=(l+r)>>1;
    if(P>mid)
        change(o<<1|1,mid+1,r);
    else
        change(o<<1,l,mid);
    a[o]=merge(a[o<<1],a[o<<1|1]);
}
int L,R;
PD question(int o,int l,int r)
{
    if(l>=L&&r<=R)
        return a[o];
    int mid=(l+r)>>1;
    if(mid>=R)
        return question(o<<1,l,mid);
    else if(mid<L)
        return question(o<<1|1,mid+1,r);
    else
        return merge(question(o<<1,l,mid),question(o<<1|1,mid+1,r));
}
int main()
{
    while(~scanf("%d%d",&n,&q))
    {
        build(1,1,n);
        while(q--)
        {
            int point;
            scanf("%d",&point);
            if(point==1)
            {
                double x,y;
                scanf("%d%lf%lf",&P,&x,&y);
                V={x/y,x/y};
                change(1,1,n);
            }
            else
            {
                scanf("%d%d",&L,&R);
                printf("%.12f\n",question(1,1,n).first);
            }
        }
    }
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;

typedef pair <double,double> PD;
int n,q;
PD a[1<<18];
PD merge(PD x,PD y)
{
    double l1,l2,r1,r2;
    l1=x.first;
    r1=x.second;
    l2=y.first;
    r2=y.second;
    double l = (l1 * l2) / (1 - (1 - l2) * r1);
    double r = r2 + ((1 - r2) * r1 * l2) / (1 - (1 - l2) * r1);
    return {l,r};
}
void build(int o,int l,int r)
{
    if(r==l)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        a[o]={x/y,x/y};//cout<<a[o].first;
        return ;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    a[o]=merge(a[o<<1],a[o<<1|1]);cout<<a[o].first<<endl;
}
PD V;
int P;
void change(int o,int l,int r)
{
    if(l==r)
    {
        a[o]=V;
        return;
    }
    int mid=(l+r)>>1;
    if(P>mid)
        change(o<<1|1,mid+1,r);
    else
        change(o<<1,l,mid);
    a[o]=merge(a[o<<1],a[o<<1|1]);
}
int L,R;
PD question(int o,int l,int r)
{
    if(l>=L&&r<=R)
        return a[o];
    int mid=(l+r)>>1;
    if(mid>=R)
        return question(o<<1,l,mid);
    else if(mid<L)
        return question(o<<1|1,mid+1,r);
    else
        return merge(question(o<<1,l,mid),question(o<<1|1,mid+1,r));
}
int main()
{
    while(~scanf("%d%d",&n,&q))
    {
        build(1,1,n);
        while(q--)
        {
            int point;
            scanf("%d",&point);
            if(point==1)
            {
                double x,y;
                scanf("%d%lf%lf",&P,&x,&y);
                V={x/y,x/y};
                change(1,1,n);
            }
            else
            {
                scanf("%d%d",&L,&R);
                printf("%.10f\n",question(1,1,n).first);
            }
        }
    }
}


#include <cstdio>
#define db double
const int M = 400005;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,m;db p[M],x[M],y[M];
void up(int i)
{
    x[i]=x[i<<1]*x[i<<1|1];
    y[i]=y[i<<1]+y[i<<1|1]*x[i<<1];
}
void ins(int i,int l,int r,int id)
{
    if(l==r)
    {
        x[i]=y[i]=p[id];
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=id) ins(i<<1,l,mid,id);
    else ins(i<<1|1,mid+1,r,id);
    up(i);
}
db ask1(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 1;
    if(L<=l && r<=R) return x[i];
    int mid=(l+r)>>1;
    return ask1(i<<1,l,mid,L,R)*ask1(i<<1|1,mid+1,r,L,R);
}
db ask2(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 0;
    if(L<=l && r<=R) return y[i];
    int mid=(l+r)>>1;db ret=0;
    ret=ask2(i<<1,l,mid,L,R);
    if(mid<R) ret+=ask1(i<<1,l,mid,L,R)*ask2(i<<1|1,mid+1,r,L,R);
    return ret;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        int u=read(),v=read();
        p[i]=1.0*(v-u)/u;
        ins(1,1,n,i);
    }
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int i=read(),u=read(),v=read();
            p[i]=1.0*(v-u)/u;
            ins(1,1,n,i);
        }
        if(op==2)
        {
            int l=read(),r=read();
            printf("%.5lf\n",1.0/(ask2(1,1,n,l,r)+1.0));
        }
    }
}


#include <cstdio>
#define db double
const int M = 400005;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,m;db p[M],x[M],y[M];
void up(int i)
{
    x[i]=x[i<<1]*x[i<<1|1];
    y[i]=y[i<<1]+y[i<<1|1]*x[i<<1];
}
void ins(int i,int l,int r,int id)
{
    if(l==r)
    {
        x[i]=y[i]=p[id];
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=id) ins(i<<1,l,mid,id);
    else ins(i<<1|1,mid+1,r,id);
    up(i);
}
db ask1(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 1;
    if(L<=l && r<=R) return x[i];
    int mid=(l+r)>>1;
    return ask1(i<<1,l,mid,L,R)*ask1(i<<1|1,mid+1,r,L,R);
}
db ask2(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 0;
    if(L<=l && r<=R) return y[i];
    int mid=(l+r)>>1;
    return ask2(i<<1,l,mid,L,R)+ask1(i<<1,l,mid,L,R)*ask2(i<<1|1,mid+1,r,L,R);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        int u=read(),v=read();
        p[i]=1.0*(v-u)/u;
        ins(1,1,n,i);
    }
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int i=read(),u=read(),v=read();
            p[i]=1.0*(v-u)/u;
            ins(1,1,n,i);
        }
        if(op==2)
        {
            int l=read(),r=read();
            printf("%.10lf\n",1.0/(ask2(1,1,n,l,r)+1));
        }
    }
}


#include <cstdio>
#define db double
const int M = 400005;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,m;db p[M],x[M],y[M];
void up(int i)
{
    x[i]=x[i<<1]*x[i<<1|1];
    y[i]=y[i<<1]+y[i<<1|1]*x[i<<1];
}
void ins(int i,int l,int r,int id)
{
    if(l==r)
    {
        x[i]=y[i]=p[id];
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=id) ins(i<<1,l,mid,id);
    else ins(i<<1|1,mid+1,r,id);
    up(i);
}
db ask1(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 1;
    if(L<=l && r<=R) return x[i];
    int mid=(l+r)>>1;
    return ask1(i<<1,l,mid,L,R)*ask1(i<<1|1,mid+1,r,L,R);
}
db ask2(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 0;
    if(L<=l && r<=R) return y[i];
    int mid=(l+r)>>1;
    return ask2(i<<1,l,mid,L,R)+ask1(i<<1,l,mid,L,R)*ask2(i<<1|1,mid+1,r,L,R);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        int u=read(),v=read();
        p[i]=1.0*(v-u)/u;
        ins(1,1,n,i);
    }
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int i=read(),u=read(),v=read();
            p[i]=1.0*(v-u)/u;
            ins(1,1,n,i);
        }
        if(op==2)
        {
            int l=read(),r=read();
            printf("%.5lf\n",1.0/(ask2(1,1,n,l,r)+1.0));
        }
    }
}


#include <cstdio>
#define db double
const int M = 400005;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,m;db p[M],x[M],y[M];
void up(int i)
{
    x[i]=x[i<<1]*x[i<<1|1];
    y[i]=y[i<<1]+y[i<<1|1]*x[i<<1];
}
void ins(int i,int l,int r,int id)
{
    if(l==r)
    {
        x[i]=y[i]=p[id];
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=id) ins(i<<1,l,mid,id);
    else ins(i<<1|1,mid+1,r,id);
    up(i);
}
db ask1(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 1;
    if(L<=l && r<=R) return x[i];
    int mid=(l+r)>>1;
    return ask1(i<<1,l,mid,L,R)*ask1(i<<1|1,mid+1,r,L,R);
}
db ask2(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 0;
    if(L<=l && r<=R) return y[i];
    int mid=(l+r)>>1;db ret=0;
    ret=ask2(i<<1,l,mid,L,R);
    ret+=ask1(i<<1,l,mid,L,R)*ask2(i<<1|1,mid+1,r,L,R);
    return ret;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        int u=read(),v=read();
        p[i]=1.0*(v-u)/u;
        ins(1,1,n,i);
    }
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int i=read(),u=read(),v=read();
            p[i]=1.0*(v-u)/u;
            ins(1,1,n,i);
        }
        if(op==2)
        {
            int l=read(),r=read();
            printf("%.5lf\n",1.0/(ask2(1,1,n,l,r)+1.0));
        }
    }
}


#include <cstdio>
#define db double
const int M = 400005;
int read()
{
    int x=0,flag=1;
    char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,m;db p[M],x[M],y[M];
void up(int i)
{
    x[i]=x[i<<1]*x[i<<1|1];
    y[i]=y[i<<1]+y[i<<1|1]*x[i<<1];
}
void ins(int i,int l,int r,int id)
{
    if(l==r)
    {
        x[i]=y[i]=p[id];
        return ;
    }
    int mid=(l+r)>>1;
    if(mid>=id) ins(i<<1,l,mid,id);
    else ins(i<<1|1,mid+1,r,id);
    up(i);
}
db ask1(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 1;
    if(L<=l && r<=R) return x[i];
    int mid=(l+r)>>1;
    return ask1(i<<1,l,mid,L,R)*ask1(i<<1|1,mid+1,r,L,R);
}
db ask2(int i,int l,int r,int L,int R)
{
    if(l>R || L>r) return 0;
    if(L<=l && r<=R) return y[i];
    int mid=(l+r)>>1;db ret=0;
    ret=ask2(i<<1,l,mid,L,R);
    if(mid<R) ret+=ask1(i<<1,l,mid,L,mid)*ask2(i<<1|1,mid+1,r,L,R);
    return ret;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        int u=read(),v=read();
        p[i]=1.0*(v-u)/u;
        ins(1,1,n,i);
    }
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int i=read(),u=read(),v=read();
            p[i]=1.0*(v-u)/u;
            ins(1,1,n,i);
        }
        if(op==2)
        {
            int l=read(),r=read();
            printf("%.5lf\n",1.0/(ask2(1,1,n,l,r)+1.0));
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
 // freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(rr<=1)
           while(1);
               if(fabs(rr)<=1.0)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(fabs(rr)<=1.0 || fabs(rr)>=1e4)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
 // freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(rr>1e15)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;

       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
//  freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(rr>1e12)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(fabs(rr)<=1)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/(double)query(1,l,r,1,n).ans);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(fabs(rr)<=1e-9)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/(double)query(1,l,r,1,n).ans);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (int x=1, int l=1,int r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    int mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(int x,int ind,long double delta,int l,int r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(int x,int low,int high,int l,int r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int  main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%d%d",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(int i=1;i<=n;i++)
   {
       int a,b;
       scanf("%d%d",&a,&b);
       input[i]=(long double)a/b;
           mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(int i=1;i<=q;i++)
   {
       int t;
       scanf("%d",&t);
       if(t==1){
           int u,a,b;
           scanf("%d%d%d",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {int l,r;
       scanf("%d%d",&l,&r);
       printf("%0.9f\n",(double)1.0/query(1,l,r,1,n).ans);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(fabs(rr)<=1.0)
           while(1);
               if(fabs(rr)<=1.0)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(fabs(rr)<=1.0 || fabs(rr)>=1e6)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
 // freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);

       printf("%0.9f\n",1.0/(double)query(1,l,r,1,n).ans);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll  n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (ll  x=1, ll  l=1,ll  r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l]+(1e-5))/(input[l]+(1e-5));
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    ll  mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(ll  x,ll  ind,long double delta,ll  l,ll  r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(ll  x,ll  low,ll  high,ll  l,ll  r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int   main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%lld%lld",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(ll  i=1;i<=n;i++)
   {
       ll  a,b;
       scanf("%lld%lld",&a,&b);
       input[i]=(long double)a/b;
         //  mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(ll  i=1;i<=q;i++)
   {
       ll  t;
       scanf("%lld",&t);
       if(t==1){
           ll  u,a,b;
           scanf("%lld%lld%lld",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {ll  l,r;
       scanf("%lld%lld",&l,&r);
       double rr=(double)query(1,l,r,1,n).ans;
       if(rr>(1e20)
           cout<<0;
       else
       printf("%0.9lf\n",1.0/rr);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,q;
long double input[100005],mul[100005];
struct po{
    long double ans;
    long double mu;
};
po segmant[400005];
void build (int x=1, int l=1,int r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(long double)(1.0-input[l])/input[l];;
        segmant[x].mu=(long double)(1.0-input[l])/input[l];return ;
    }
    int mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(int x,int ind,long double delta,int l,int r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(long double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(int x,int low,int high,int l,int r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int  main(){
  //freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%d%d",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(int i=1;i<=n;i++)
   {
       int a,b;
       scanf("%d%d",&a,&b);
       input[i]=(long double)a/b;
           mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(int i=1;i<=q;i++)
   {
       int t;
       scanf("%d",&t);
       if(t==1){
           int u,a,b;
           scanf("%d%d%d",&u,&a,&b);
           update(1,u,(long double)a/b,1,n);
       }
       else
       {int l,r;
       scanf("%d%d",&l,&r);

       printf("%0.9f\n",1.0/(double)query(1,l,r,1,n).ans);

       }

   }
   return 0;}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,q;
double input[100005],mul[100005];
struct po{
    double ans;
    double mu;
};
po segmant[400005];
void build (int x=1, int l=1,int r=n)
{
    if(l==r)
    {
        segmant[x].ans=1+(double)(1.0-input[l])/input[l];;
        segmant[x].mu=(double)(1.0-input[l])/input[l];return ;
    }
    int mid=(l+r)/2;
    build(2*x,l,mid);
    build(2*x+1,mid+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
void update(int x,int ind,double delta,int l,int r){
    if(ind<l || ind>r)
        return ;
    if(ind==l && ind==r){
        segmant[x].mu=(1.0-delta)/delta;
        segmant[x].ans=1+(double)(1.0-delta)/delta;
        return ;}
    update(2*x,ind,delta,l,(r+l)/2);
    update(2*x+1,ind,delta,(l+r)/2+1,r);
    segmant[x].ans=segmant[2*x].ans+segmant[2*x].mu*(segmant[2*x+1].ans-1);
    segmant[x].mu=segmant[2*x].mu*segmant[2*x+1].mu;
}
po re;
po query(int x,int low,int high,int l,int r){
    if(high<l || low>r)
        return re;
    if(low<=l && high>=r)
        return segmant[x];
    po p1,p2,p;
    p1= query(2*x,low,high,l,(r+l)/2);
   p2= query(2*x+1,low,high,(l+r)/2+1,r);
   p.ans=p1.ans+p1.mu*(p2.ans-1);
   p.mu=p1.mu*p2.mu;
   return p;
}
int  main(){
 // freopen("in","r",stdin);
  //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
  scanf("%d%d",&n,&q);
   mul[0]=1;
   re.ans=1;
   re.mu=1;
   for(int i=1;i<=n;i++)
   {
       int a,b;
       scanf("%d%d",&a,&b);
       input[i]=(double)a/b;
           mul[i]=mul[i-1]*(1-input[i])/input[i];
   }
   build();
   for(int i=1;i<=q;i++)
   {
       int t;
       scanf("%d",&t);
       if(t==1){
           int u,a,b;
           scanf("%d%d%d",&u,&a,&b);
           update(1,u,(double)a/b,1,n);
       }
       else
       {int l,r;
       scanf("%d%d",&l,&r);
       printf("%0.9f\n",1.0/query(1,l,r,1,n).ans);

       }

   }
   return 0;}