#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000009
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost ios::sync_with_stdio(false);

ll a[1000001],b[1000001],h[1000001];
double l[1000001],r[1000001],tree[4000001],z[1000001];
map<ll,ll>assign;
vector<ll>v;

void build(ll node,ll a,ll b)
{
	tree[node]=1.0;
	if(a!=b)
	{
		ll mid=(a+b)/2;
		build(2*node,a,mid);
		build(2*node+1,mid+1,b);
	}
}
void update(ll node,ll a,ll b,ll l,ll r,double val)
{
	if(a>b || a>r || b<l)
	return;
	if(a>=l && b<=r)
	{
		tree[node]*=val;
		//return;
	}
	ll mid=(a+b)/2;
	if(a!=b){
	update(2*node,a,mid,l,r,val);
	update(2*node+1,mid+1,b,l,r,val);}
}
double query(ll node,ll a,ll b,ll l,ll r)
{
	if(a>b || a>r || b<l)
	return 1.0;
	if(a>=l && b<=r)
	return tree[node];
	ll mid=(a+b)/2;
	return query(2*node,a,mid,l,r)*query(2*node+1,mid+1,b,l,r);
}
int main()
{
	cout<<fixed<<setprecision(10);
	ll i,j,n,m,x,y,size;
	double ans=0.0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>a[i]>>h[i]>>l[i]>>r[i];
		v.pb(a[i]-1);
		v.pb(a[i]+1);
		v.pb(a[i]+h[i]);
		v.pb(a[i]-h[i]);
		l[i]/=100.0;;
		r[i]/=100.0;
	}
	for(i=1;i<=m;i++)
	{
		cin>>b[i]>>z[i];
		v.pb(b[i]);
	}
	sort(all(v));
	for(i=0;i<v.size();i++)
	assign[v[i]]=i+1;
	size=v.size();
	size++;
	build(1,1,size);
	for(i=1;i<=n;i++)
	{
		update(1,1,size,assign[a[i]+1],assign[a[i]+h[i]],1-r[i]);
		update(1,1,size,assign[a[i]-h[i]],assign[a[i]-1],1-l[i]);
	}
	for(i=1;i<=m;i++)
	ans+=query(1,1,size,assign[b[i]],assign[b[i]])*z[i];
	cout<<ans;
	return 0;
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000009
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost ios::sync_with_stdio(false);

ll a[1000001],b[1000001],h[1000001];
double l[1000001],r[1000001],tree[4000001],z[1000001];
map<ll,ll>assign;
vector<ll>v;

void build(ll node,ll a,ll b)
{
	tree[node]=1.0;
	if(a!=b)
	{
		ll mid=(a+b)/2;
		build(2*node,a,mid);
		build(2*node+1,mid+1,b);
	}
}
void update(ll node,ll a,ll b,ll l,ll r,double val)
{
	if(a>b || a>r || b<l)
	return;
	if(a>=l && b<=r)
	{
		tree[node]*=val;
		//return;
	}
	ll mid=(a+b)/2;
	if(a!=b){
	update(2*node,a,mid,l,r,val);
	update(2*node+1,mid+1,b,l,r,val);}
}
double query(ll node,ll a,ll b,ll l,ll r)
{
	if(a>b || a>r || b<l)
	return 1.0;
	if(a>=l && b<=r)
	return tree[node];
	ll mid=(a+b)/2;
	return query(2*node,a,mid,l,r)*query(2*node+1,mid+1,b,l,r);
}
int main()
{
	boost;
	cout<<fixed<<setprecision(10);
	ll i,j,n,m,x,y,size;
	double ans=0.0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>a[i]>>h[i]>>l[i]>>r[i];
		v.pb(a[i]-1);
		v.pb(a[i]+1);
		v.pb(a[i]+h[i]);
		v.pb(a[i]-h[i]);
		l[i]/=100.0;;
		r[i]/=100.0;
	}
	for(i=1;i<=m;i++)
	{
		cin>>b[i]>>z[i];
		v.pb(b[i]);
	}
	sort(all(v));
	for(i=0;i<v.size();i++)
	assign[v[i]]=i+1;
	size=v.size();
	size++;
	build(1,1,size);
	for(i=1;i<=n;i++)
	{
		update(1,1,size,assign[a[i]+1],assign[a[i]+h[i]],1-r[i]);
		update(1,1,size,assign[a[i]-h[i]],assign[a[i]-1],1-l[i]);
	}
	for(i=1;i<=m;i++)
	ans+=query(1,1,size,assign[b[i]],assign[b[i]])*z[i];
	cout<<ans;
	return 0;
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll  int
#define inf 1000000000000
#define mod 1000000009
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost ios::sync_with_stdio(false);

ll a[1000001],b[1000001],h[1000001];
double l[1000001],r[1000001],tree[4000001],z[1000001];
map<ll,ll>assign;
vector<ll>v;

void build(ll node,ll a,ll b)
{
	tree[node]=1.0;
	if(a!=b)
	{
		ll mid=(a+b)/2;
		build(2*node,a,mid);
		build(2*node+1,mid+1,b);
	}
}
void update(ll node,ll a,ll b,ll l,ll r,double val)
{
	if(a>b || a>r || b<l)
	return;
	if(a>=l && b<=r)
	{
		tree[node]*=val;
		return;
	}
	ll mid=(a+b)/2;
	if(a!=b){
	update(2*node,a,mid,l,r,val);
	update(2*node+1,mid+1,b,l,r,val);}
}
double query(ll node,ll a,ll b,ll l,ll r)
{
	if(a>b || a>r || b<l)
	return 1.0;
	if(a>=l && b<=r)
	return tree[node];
	ll mid=(a+b)/2;
	return tree[node]*query(2*node,a,mid,l,r)*query(2*node+1,mid+1,b,l,r);
}
int main()
{
//	boost;
	cout<<fixed<<setprecision(10);
	ll i,j,n,m,x,y,size;
	double ans=0.0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		scanf("%d %d %lf %lf",&a[i],&h[i],&l[i],&r[i]);
		v.pb(a[i]-1);
		v.pb(a[i]+1);
		v.pb(a[i]+h[i]);
		v.pb(a[i]-h[i]);
		l[i]/=100.0;;
		r[i]/=100.0;
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d %lf",&b[i],&z[i]);
		v.pb(b[i]);
	}
	sort(all(v));
	for(i=0;i<v.size();i++)
	assign[v[i]]=i+1;
	size=v.size();
	size++;
	build(1,1,size);
	for(i=1;i<=n;i++)
	{
		update(1,1,size,assign[a[i]+1],assign[a[i]+h[i]],1-r[i]);
		update(1,1,size,assign[a[i]-h[i]],assign[a[i]-1],1-l[i]);
	}
	for(i=1;i<=m;i++)
	ans+=query(1,1,size,assign[b[i]],assign[b[i]])*z[i];
	cout<<ans;
	return 0;
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll  int
#define inf 1000000000000
#define mod 1000000009
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost ios::sync_with_stdio(false);

ll a[1000001],b[1000001],h[1000001];
double l[1000001],r[1000001],tree[4000001],z[1000001];
map<ll,ll>assign;
vector<ll>v;

void build(ll node,ll a,ll b)
{
	tree[node]=1.0;
	if(a!=b)
	{
		ll mid=(a+b)/2;
		build(2*node,a,mid);
		build(2*node+1,mid+1,b);
	}
}
void update(ll node,ll a,ll b,ll l,ll r,double val)
{
	if(a>b || a>r || b<l)
	return;
	if(a>=l && b<=r)
	{
		tree[node]*=val;
	//	return;
	}
	ll mid=(a+b)/2;
	if(a!=b){
	update(2*node,a,mid,l,r,val);
	update(2*node+1,mid+1,b,l,r,val);}
}
double query(ll node,ll a,ll b,ll l,ll r)
{
	if(a>b || a>r || b<l)
	return 1.0;
	if(a>=l && b<=r)
	return tree[node];
	ll mid=(a+b)/2;
	return query(2*node,a,mid,l,r)*query(2*node+1,mid+1,b,l,r);
}
int main()
{
//	boost;
	cout<<fixed<<setprecision(10);
	ll i,j,n,m,x,y,size;
	double ans=0.0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		scanf("%d %d %lf %lf",&a[i],&h[i],&l[i],&r[i]);
		v.pb(a[i]-1);
		v.pb(a[i]+1);
		v.pb(a[i]+h[i]);
		v.pb(a[i]-h[i]);
		l[i]/=100.0;;
		r[i]/=100.0;
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d %lf",&b[i],&z[i]);
		v.pb(b[i]);
	}
	sort(all(v));
	for(i=0;i<v.size();i++)
	assign[v[i]]=i+1;
	size=v.size();
	size++;
	build(1,1,size);
	for(i=1;i<=n;i++)
	{
		update(1,1,size,assign[a[i]+1],assign[a[i]+h[i]],1-r[i]);
		update(1,1,size,assign[a[i]-h[i]],assign[a[i]-1],1-l[i]);
	}
	for(i=1;i<=m;i++)
	ans+=query(1,1,size,assign[b[i]],assign[b[i]])*z[i];
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef long double ld;

struct Event
{
  int t; // 0 - divide, 1 - mul, 2 - sum, 3 - mushroom
  int x; // coordinate
  ld val; // val
  int pp;
  Event(){}
  Event(int t, int x, ld val, int pp=0)
    : t(t), x (x), val (val), pp(pp){}
  bool operator<(const Event& e)const
  {
    if(x != e.x) return x < e.x;
    return t < e.t;
  }
};

int main()
{
  int n, m;
  scanf("%d%d", &n, &m);
  vector<Event> E;
  for(int i=1;i<=n;++i)
  {
    int a, h, l, r;
    scanf("%d%d%d%d", &a, &h, &l, &r);
    if(l != 100)
    {
      E.emplace_back(0, a, log2((100 - l) / (ld) 100));
      E.emplace_back(1, a-h, log2((100 - l) / (ld) 100));
    }else
    {
      E.emplace_back(2, a-h, 0, 1);
      E.emplace_back(2, a, 0, -1);
    }
    if(r != 100)
    {
      E.emplace_back(0, a+h+1, log2((100 - r) / (ld) 100));
      E.emplace_back(1, a+1, log2((100 - r) / (ld) 100));
    }else
    {
      E.emplace_back(2, a+1, 0, 1);
      E.emplace_back(2, a+h+1, 0, -1);
    }
  }
  for(int i=1;i<=m;++i)
  {
    int b, z;
    scanf("%d%d", &b, &z);
    E.emplace_back(3, b, z);
  }

  sort(E.begin(), E.end());
  ld cur = 0.0, ans = 0.0;
  int sum = 0;
  for(auto e: E)
  {
    if(e.t == 0)
    {
      cur -= e.val;
    }else if(e.t == 1)
    {
      cur += e.val;
    }else if(e.t == 2)
    {
      sum += e.pp;
    }else
    {
      //~ cerr << "mushroom at " << e.x << " value = " << e.val << ' ' << sum << ' ' << cur << endl;
      if(sum == 0)
        ans += pow(2.0, log2(e.val) + cur);
    }
  }

  cout << fixed << setprecision(12) << ans << endl;

  return 0;
}
//hello


//#pragma optimization_level 3

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <chrono>
#include <ctime>
#include <queue>
#include <math.h>
#include <deque>
#include <stack>
#include <iomanip>
#include <assert.h>
#include <stdio.h>
#include <cstring>
#include <random>

using namespace std;

#define int long long
#define ll long long
#define ld long double
#define ull unsigned long long
#define endl '\n'
#define try tr
#define pii pair<int, int>
#define ti tuple <int, int, int>
#define vi vector <int>
#define vpi vector <pii>
#define umap unordered_map
#define uset unordered_set
#define left left11
#define right right11
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define sqr(a) ((a) * (a))
#define fast ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

#define fs first
#define sc second

ld TL = 1.0;
bool is_tl = 0;
int CALLS = 0;

inline bool IS() {
    if (++CALLS == 1000) {
        CALLS = 0;
        is_tl |= clock() > (TL - 0.1) * CLOCKS_PER_SEC;
    }
    return is_tl;
}

template<typename T1, typename T2>
inline void amin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void amax(T1 &a, T2 b) { if (a < b) a = b; }

template<typename T1, typename T2>
ostream &operator<<(ostream &os, pair<T1, T2> &p) {
    os << p.first << ' ' << p.second << endl;
    return os;
}

template<typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
    is >> p.first >> p.second;
    return is;
}

template<typename T>
ostream &operator<<(ostream &os, vector<T> &v) {
    for (auto &u : v) os << u << ' ';
    os << endl;
    return os;
}

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
const ll N = 1e6 + 7, NS = 2e3 + 7, lg = 19, sq = 550, inf = 1e18 + 7, SM = 1e2 + 7;
const ld eps = 1e-9;
int hash_mod[4] = {1000000007, 998244353, 1000000009, 999999937}, mod = hash_mod[rnd() % 4];
int hash_pows[4] = {179, 239, 1007, 2003}, P = hash_pows[rnd() % 4];
struct segtree{
    int n;
    vector <ld> add, t;
    void init(int _n) {
        n = _n;
        add.resize(4 * n, 1.0);
        t.resize(4 * n, 1.0);
    }
    void push(int v, int l, int r) {
        t[v] *= add[v];
        if(l != r - 1) {
            add[2 * v] *= add[v];
            add[2 * v + 1] *= add[v];
        }
        add[v] = 1.0;
    }
    void update(int v, int l, int r, int vl, int vr, ld x) {
        push(v, l, r);
        if(l >= vr || vl >= r)
            return;
        if(l >= vl && r <= vr) {
            add[v] *= x;
            push(v, l, r);
            return;
        }
        int m = (l + r) / 2;
        update(2 * v, l, m, vl, vr, x);
        update(2 * v + 1, m, r, vl, vr, x);
    }
    void update(int l, int r, ld x) {
        update(1, 0, n, l, r, x);
    }
    ld get(int v, int l, int r, int pos) {
        push(v, l, r);
        if(l == r - 1) {
            return t[v];
        }
        int m = (l + r) / 2;
        if(pos < m)
            return get(2 * v, l, m, pos);
        else
            return get(2 * v + 1, m, r, pos);
    }
    ld get(int pos) {
        return get(1, 0, n, pos);
    }
} T;
struct tree{
    int pos;
    int h;
    ld l;
    ld r;
    tree(int _pos, int _h, int _l, int _r) {
        pos = _pos;
        h = _h;
        l = _l;
        r = _r;
    }
};
vector <tree> v;
vpi mush;
void solve() {
    vi st;
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        int a, h, l, r;
        cin >> a >> h >> l >> r;
        st.pb(a + h);
        st.pb(a - 1);
        st.pb(a - h);
        st.pb(a + 1);
        v.pb(tree(a, h, l, r));
    }
    for (int i = 0; i < m; i++) {
        pii p;
        cin >> p;
        mush.pb(p);
        st.pb(p.first);
    }
    sort(all(st));
    st.erase(unique(all(st)), st.end());
    T.init(st.size());
    for (int i = 0; i < n; i++) {
        int l, r;
        ld x;
        l = lower_bound(all(st), (v[i].pos - v[i].h)) - st.begin();
        r = lower_bound(all(st), v[i].pos - 1) - st.begin();
        x = (100.0 - v[i].l) / (100.0);
     //   cout << l << ' ' << r << ' ' << x << endl;
        T.update(l, r + 1, x);
        r = lower_bound(all(st), (v[i].pos + v[i].h)) - st.begin();
        l = lower_bound(all(st), v[i].pos + 1) - st.begin();
        x = (100.0 - v[i].r) / (100.0);
       // cout << l << ' ' << r << ' ' << x << endl;
        T.update(l, r + 1, x);
    }
    ld ans = 0;
    for (auto u : mush) {
        u.first = lower_bound(all(st), u.first) - st.begin();
       // cout << u.first << ' ' << T.get(u.first) << endl;
        ans += T.get(u.first) * (0.0 + u.second);
    }
    cout << fixed << setprecision(10);
cout << ans;
}

signed main() {
    fast
    solve();
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f
#define eps 1e-8

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1.0;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = (100-ll)/100.0,r[i] = (100-rr)/100.0;
    if (ll == 100) {
        l[i] += eps;
        r[i] -= eps;
    } else if (rr == 100) {
        l[i] -= eps;
        r[i] += eps;
    }
    }
    }
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
	add(ll,r[i]);
	add(rr+1,1.0/r[i]);
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
	add(ll,l[i]);
	add(rr+1,1.0/l[i]);
    }
  }
  ans = 0;

  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f
#define eps 1e-8

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1.0;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = (100-ll)/100.0,r[i] = (100-rr)/100.0;
    if (ll == 100) {
      l[i] += eps;
      r[i] -= eps;
    } else if (rr == 100) {
      l[i] -= eps;
      r[i] += eps;
    }
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
      add(ll,r[i]);
      add(rr+1,1.0/r[i]);
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
      add(ll,l[i]);
      add(rr+1,1.0/l[i]);
    }
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1.0;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = 0.01*(100-ll),r[i] = 0.01*(100-rr);
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
      add(ll,r[i]);
      add(rr+1,1.0/r[i]);
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
      add(ll,l[i]);
      add(rr+1,1.0/l[i]);
    }
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f
#define eps 1e-8

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],ans;
class segment_tree {
public:
  int l,r;
  double p;//
}st[1<<18];

void init_st(int i,int l,int r) {
  st[i].l = l;
  st[i].r = r;
  st[i].p = 1;//probability that this interval survive
  if (l < r) {
    int mid = (l+r)>>1;
    init_st(i<<1,l,mid);
    init_st((i<<1)+1,mid+1,r);
  }
}

void push_down(int i) {
  if (st[i].p != 1) {
    st[i<<1].p *= st[i].p;
    st[(i<<1)+1].p *= st[i].p;
    st[i].p = 1;
  }
}

void update(int i,int l,int r,double p) {
  if (st[i].l >= l && st[i].r <= r) {
    st[i].p *= p;
    return;
  }
  push_down(i);
  int mid = (st[i].l + st[i].r)>>1;
  if (l <= mid) update(i<<1,l,r,p);
  if (r > mid) update((i<<1)+1,l,r,p);
}

double query(int i,int pos) {
  if (st[i].l == st[i].r) return st[i].p;
  push_down(i);
  int mid = (st[i].l + st[i].r)>>1;
  if (pos <= mid) return query(i<<1,pos);
  return query((i<<1)+1,pos);
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = (100-ll)/100.0,r[i] = (100-rr)/100.0;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  init_st(1,1,cnt);
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) update(1,ll,rr,r[i]);
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) update(1,ll,rr,l[i]);
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += query(1,pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f
#define eps 1e-8

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M],kill[N];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1.0;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = (100-ll)/100.0,r[i] = (100-rr)/100.0;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  memset(kill,0,sizeof(kill));
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
      if (r[i] > eps) {//>0,otherwise all killed
	add(ll,r[i]);
	add(rr+1,1.0/r[i]);
      } else for (int i = ll; i <= rr; ++i) kill[i] = 1;//kill a range of position
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
      if (l[i] > eps) {
	add(ll,l[i]);
	add(rr+1,1.0/l[i]);
      } else for (int i = ll; i <= rr; ++i) kill[i] = 1;
    }
  }
  ans = 0;

  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i]*(1-kill[pos]);
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f
#define eps 1e-8

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],ans;
class segment_tree {
public:
  int l,r;
  double p;//
}st[1<<18];

void init_st(int i,int l,int r) {
  st[i].l = l;
  st[i].r = r;
  st[i].p = 1;//probability that this interval survive
  if (l < r) {
    int mid = (l+r)>>1;
    init_st(i<<1,l,mid);
    init_st((i<<1)+1,mid+1,r);
  }
}

void push_down(int i) {
  if (st[i].p != 1) {
    st[i<<1].p *= st[i].p;
    st[(i<<1)+1].p *= st[i].p;
    st[i].p = 1;
  }
}

void update(int i,int l,int r,double p) {
  if (st[i].l >= l && st[i].r <= r) {
    st[i].p *= p;
    return;
  }
  push_down(i);
  int mid = (st[i].l + st[i].r)>>1;
  if (l <= mid) update(i<<1,l,r,p);
  if (r > mid) update((i<<1)+1,l,r,p);
}

double query(int i,int pos) {
  if (st[i].l == st[i].r) return st[i].p;
  push_down(i);
  int mid = (st[i].l + st[i].r)>>1;
  if (pos <= mid) return query(i<<1,pos);
  return query((i<<1)+1,pos);
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = (100-ll)/100.0,r[i] = (100-rr)/100.0;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  init_st(1,1,cnt);
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) update(1,ll,rr,l[i]);
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) update(1,ll,rr,r[i]);
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += query(1,pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = 0.01*ll,r[i] = 0.01*rr;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
      add(ll,1-r[i]);
      add(rr+1,1.0/(1-r[i]));
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
      add(ll,1-l[i]);
      add(rr+1,1.0/(1-l[i]));
    }
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i];
  }
  printf("%.4lf\n",ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100005
#define M 10005
#define INF 0x3f3f3f3f

int n,m,a[N],h[N],dd[M],cnt,b[M],z[M];
double l[N],r[N],pp[N],ans;

void add(int i,double p) {
  while (i <= cnt) {
    pp[i] *= p;
    i += i&(-i);
  }
}

double sum(int i) {
  double res = 1;
  while (i > 0) {
    res *= pp[i];
    i -= i&(-i);
  }
  return res;
}

int main() {
  scanf("%d%d",&n,&m);
  for (int i = 0,ll,rr; i < n; ++i) {
    scanf("%d%d%d%d",a+i,h+i,&ll,&rr);
    l[i] = 0.01*ll,r[i] = 0.01*rr;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d",b+i,z+i);
    dd[i+1] = b[i];
  }
  std::sort(dd+1,dd+m+1);
  cnt = std::unique(dd+1,dd+m+1)-dd-1;
  for (int i = 1; i <= cnt; ++i) pp[i] = 1;
  for (int i = 0,ll,rr; i < n; ++i) {
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]+1)-dd;//ll == cnt???
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]+h[i])-dd-1;
    if (ll <= rr) {
      add(ll,1-r[i]);
      add(rr+1,1.0/(1-r[i]));
    }
    ll = std::lower_bound(dd+1,dd+cnt+1,a[i]-h[i])-dd;
    rr = std::upper_bound(dd+1,dd+cnt+1,a[i]-1)-dd-1;//problem?
    if (ll <= rr) {
      add(ll,1-l[i]);
      add(rr+1,1.0/(1-l[i]));
    }
  }
  ans = 0;
  for (int i = 0,pos; i < m; ++i) {
    pos = std::lower_bound(dd+1,dd+cnt+1,b[i])-dd;
    ans += sum(pos)*z[i];
  }
  printf("%lf\n",ans);
  return 0;
}


#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int N=1e5+5;
struct OP
{
    double flag;
    int st,ed,lft;
    OP(){}
    OP(int a,int b,double c,int d){st=a;ed=b;flag=c;lft=d;}
};
struct node
{
    double P;
    int lft,rht,flag;
    void fun(double tmp)
    {
        P*=tmp;
        flag=1;
    }
};
int B[N],Z[N];
vector<OP> op;
vector<int> Y;
map<int,int> H;
struct Segtree{
    node tree[N*4*4];
    void Pushdown(int rt){
        if(tree[rt].flag){
            tree[rt<<1].fun(tree[rt].P);
            tree[rt<<1|1].fun(tree[rt].P);
            tree[rt].flag=0; tree[rt].P=1;
        }
    }
    void build(int l,int r,int rt){
        tree[rt].lft=l; tree[rt].rht=r;
        tree[rt].P=1;   tree[rt].flag=0;
        if(l==r) return;
        int m=(l+r)>>1;
        build(l,m,rt<<1); build(m+1,r,rt<<1|1);
    }
    void update(int L,int R,int rt,double tmp){
        int l=tree[rt].lft; int r=tree[rt].rht;
        if(L<=l && r<=R) tree[rt].fun(tmp);
        else {
            Pushdown(rt);
            int m=(l+r)>>1;
            if(L<=m) update(L,R,rt<<1,tmp);
            if(R>m)  update(L,R,rt<<1|1,tmp);
        }
    }
    double query(int pos,int rt){
        int l=tree[rt].lft; int r=tree[rt].rht;
        if(l==r) return  tree[rt].P;
        else {
            Pushdown(rt);
            int m=(l+r)>>1;
            if(pos<=m) return query(pos,rt<<1);
            else return query(pos,rt<<1|1);
        }
    }
}seg;
int main(){
    int n,m;
    int i,j,k;
    while(~scanf("%d %d",&n,&m)){
        Y.clear(); op.clear(); H.clear();

        for(i=0;i<n;i++){
            int a,b,c,d; scanf("%d %d %d %d",&a,&b,&c,&d);
            Y.push_back(a-b); Y.push_back(a+b); Y.push_back(a);
            op.push_back(OP(a-b,a,(100-c)/100.0,1)); op.push_back(OP(a,a+b,(100-d)/100.0,0));
        }

        for(i=0;i<m;i++){
            //printf("hehe\n");
            scanf("%d %d",&B[i],&Z[i]); Y.push_back(B[i]);
        }
        sort(Y.begin(),Y.end());
        Y.erase(unique(Y.begin(),Y.end()),Y.end());
        for(i=0;i<Y.size();i++) H[Y[i]]=i;
        seg.build(0,Y.size()-1,1);
        for(i=0;i<op.size();i++){
            if(op[i].lft) seg.update(H[op[i].st],H[op[i].ed]-1,1,op[i].flag);
            else seg.update(H[op[i].st]+1,H[op[i].ed],1,op[i].flag);
        }
        double ans=0;
        for(i=0;i<m;i++){
            ans+=Z[i]*seg.query(H[B[i]],1);
        }
        printf("%.4f\n",ans);
    }
    return 0;
}

/*

1 1
2 2 50 50
1 1

*/


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
int n,m,cnt,pos[N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
//		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000

*/


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1000005;
int n,m,cnt,pos[4*N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
//		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000

*/


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
int n,m,cnt,pos[N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

//	for (int i=0; i<cnt; i++) {
//		printf("##%d %lf\n",pos[i],1.0-query(1, i));
//	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000
*/


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
int n,m,cnt,pos[N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
//		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000

3 3
2 5 67 8
-5 5 56 13
0 7 32 5
2 8
-1 5
-1 7

*/#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
int n,m,cnt,pos[N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
//		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000

3 3
2 5 67 8
-5 5 56 13
0 7 32 5
2 8
-1 5
-1 7

*/


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
int n,m,cnt,pos[4*N];
double ans,sum;
struct mushroom{
	int a,b;
	double v;
}mo[N];
struct tree{
	int a,h,l,r,m;
	double p1,p2;
}ya[N];
struct segment{
	int l,r;
	double tag,p;
}tr[4*N];
void build(int k,int l,int r) {
	tr[k].l=l;
	tr[k].r=r;
	tr[k].tag=1;
	tr[k].p=1;
	if (l==r) {
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void down(int k) {
	tr[k<<1].tag*=tr[k].tag;
	tr[k<<1|1].tag*=tr[k].tag;
	tr[k<<1].p*=tr[k].tag;
	tr[k<<1|1].p*=tr[k].tag;
	tr[k].tag=1.0;
}
void update(int k,int l,int r,double p) {
	if (l<=tr[k].l && tr[k].r<=r) {
		tr[k].tag*=p;
		tr[k].p*=p;
		return;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (l<=mid) update(k<<1, l, r, p);
	if (mid<r) update(k<<1|1, l, r, p);
}
double query(int k,int q) {
	if (tr[k].l==tr[k].r && tr[k].l==q) {
		return tr[k].p;
	}
	down(k);
	int mid=(tr[k].l+tr[k].r)>>1;
	if (q<=mid) return query(k<<1, q);
	return query(k<<1|1, q);
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i=1; i<=n; i++) {
		scanf("%d%d%lf%lf",&ya[i].a,&ya[i].h,&ya[i].p1,&ya[i].p2);
		pos[cnt++]=ya[i].a;
		pos[cnt++]=ya[i].a-ya[i].h;
		pos[cnt++]=ya[i].a+ya[i].h;
	}
	for (int i=1; i<=m; i++) {
		scanf("%d%lf",&mo[i].a,&mo[i].v);
		pos[cnt++]=mo[i].a;
		sum+=mo[i].v;
	}
	sort(pos, pos+cnt);
	int tot=cnt;
	cnt=1;
	for (int i=1; i<tot; i++) {
		if (pos[i]!=pos[cnt-1]) pos[cnt++]=pos[i];
	}

//	cout << endl;
//	for (int i=0; i<cnt; i++) {
//		printf("#%d ",pos[i]);
//	}
//	cout << endl;

	for (int i=1; i<=n; i++) {
		ya[i].m=lower_bound(pos, pos+cnt, ya[i].a)-pos;
		ya[i].l=lower_bound(pos, pos+cnt, ya[i].a-ya[i].h)-pos;
		ya[i].r=lower_bound(pos, pos+cnt, ya[i].a+ya[i].h)-pos;

//		printf("#%d %d %d\n",ya[i].m,ya[i].l,ya[i].r);

	}
	for (int i=1; i<=m; i++) {
		mo[i].b=lower_bound(pos, pos+cnt, mo[i].a)-pos;

//		printf("#%d\n",mo[i].b);
	}

//	cout << endl;

	build(1,0,cnt-1);

	for (int i=1; i<=n; i++) {

//		cout << ya[i].m << " " << ya[i].m << " " << 1.0-(ya[i].p1+ya[i].p2)/100.0 << endl;
//		update(1,ya[i].m,ya[i].m,1.0-(ya[i].p1+ya[i].p2)/100.0);

		if (ya[i].l<=ya[i].m-1) {
//			cout << ya[i].l << " " << ya[i].m-1 << " " << 1.0-(ya[i].p1)/100.0 << endl;
			update(1,ya[i].l,ya[i].m-1,1.0-(ya[i].p1)/100.0);
		}

		if (ya[i].m+1<=ya[i].r) {
//			cout << ya[i].m+1 << " " << ya[i].r << " " << 1.0-(ya[i].p2)/100.0 << endl;
			update(1,ya[i].m+1,ya[i].r,1.0-(ya[i].p2)/100.0);
		}

	}

	for (int i=1; i<=m; i++) {
		ans+=(1.0-query(1,mo[i].b))*mo[i].v;
	}

	printf("%lf",sum-ans);

	return 0;
}
/*
1 1
2 2 50 50
1 1
Output
0.5000000000

Input
2 1
2 2 50 50
4 2 50 50
3 1
Output
0.2500000000

*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=1e5+5;
struct OP
{
    double flag;
    int st,ed,lft;
    OP(){}
    OP(int a,int b,double c,int d){st=a;ed=b;flag=c;lft=d;}
};
struct node
{
    double P;
    int lft,rht,flag;
    int mid(){return MID(lft,rht);}
    void fun(double tmp)
    {
        P*=tmp;
        flag=1;
    }
};
int B[N],Z[N];
vector<OP> op;
vector<int> Y;
map<int,int> H;
struct Segtree
{
    node tree[N*4*4];
    void PushDown(int ind)
    {
        if(tree[ind].flag)
        {
            tree[LL(ind)].fun(tree[ind].P);
            tree[RR(ind)].fun(tree[ind].P);
            tree[ind].flag=0;   tree[ind].P=1;
        }
    }
    void build(int lft,int rht,int ind)
    {
        tree[ind].lft=lft;  tree[ind].rht=rht;
        tree[ind].P=1;      tree[ind].flag=0;
        if(lft!=rht)
        {
            int mid=tree[ind].mid();
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
        }
    }
    void updata(int st,int ed,int ind,double flag)
    {
        int lft=tree[ind].lft,rht=tree[ind].rht;
        if(st<=lft&&rht<=ed) tree[ind].fun(flag);
        else
        {
            PushDown(ind);
            int mid=tree[ind].mid();
            if(st<=mid) updata(st,ed,LL(ind),flag);
            if(ed> mid) updata(st,ed,RR(ind),flag);
        }
    }
    double query(int pos,int ind)
    {
        if(tree[ind].lft==tree[ind].rht) return tree[ind].P;
        else
        {
            PushDown(ind);
            int mid=tree[ind].mid();
            if(pos<=mid) return query(pos,LL(ind));
            else return query(pos,RR(ind));
        }
    }
}seg;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Y.clear(); H.clear(); op.clear();

        for(int i=0;i<n;i++)
        {
            int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
            Y.push_back(a-b); Y.push_back(a+b);
            Y.push_back(a);
            op.push_back(OP(a-b,a,(100-c)/100.0,1));
            op.push_back(OP(a,a+b,(100-d)/100.0,0));
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&B[i],&Z[i]);
            Y.push_back(B[i]);
        }
        sort(Y.begin(),Y.end());
        Y.erase(unique(Y.begin(),Y.end()),Y.end());
        for(int i=0;i<(int)Y.size();i++) H[Y[i]]=i;

        seg.build(0,(int)Y.size(),1);
        for(int i=0;i<(int)op.size();i++)
        {
            if(op[i].lft) seg.updata(H[op[i].st],H[op[i].ed]-1,1,op[i].flag);
            else seg.updata(H[op[i].st]+1,H[op[i].ed],1,op[i].flag);
        }
        double res=0;
        for(int i=0;i<m;i++)
        {
            res+=Z[i]*seg.query(H[B[i]],1);
        }
        printf("%.4lf\n",res);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=1e5+5;
struct OP
{
    double flag;
    int st,ed,lft;
    OP(){}
    OP(int a,int b,double c,int d){st=a;ed=b;flag=c;lft=d;}
};
struct node
{
    double P;
    int lft,rht,flag;
    int mid(){return MID(lft,rht);}
    void fun(double tmp)
    {
        P*=tmp;
        flag=1;
    }
};
int B[N],Z[N];
vector<OP> op;
vector<int> Y;
map<int,int> H;
struct Segtree
{
    node tree[N*4*4];
    void PushDown(int ind)
    {
        if(tree[ind].flag)
        {
            tree[LL(ind)].fun(tree[ind].P);
            tree[RR(ind)].fun(tree[ind].P);
            tree[ind].flag=0;   tree[ind].P=1;
        }
    }
    void build(int lft,int rht,int ind)
    {
        tree[ind].lft=lft;  tree[ind].rht=rht;
        tree[ind].P=1;      tree[ind].flag=0;
        if(lft!=rht)
        {
            int mid=tree[ind].mid();
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
        }
    }
    void updata(int st,int ed,int ind,double flag)
    {
        int lft=tree[ind].lft,rht=tree[ind].rht;
        if(st<=lft&&rht<=ed) tree[ind].fun(flag);
        else
        {
            //PushDown(ind);
            int mid=tree[ind].mid();
            if(st<=mid) updata(st,ed,LL(ind),flag);
            if(ed> mid) updata(st,ed,RR(ind),flag);
        }
    }
    double query(int pos,int ind)
    {
        if(tree[ind].lft==tree[ind].rht) return tree[ind].P;
        else
        {
            //PushDown(ind);
            int mid=tree[ind].mid();
            if(pos<=mid) return query(pos,LL(ind));
            else return query(pos,RR(ind));
        }
    }
}seg;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Y.clear(); H.clear(); op.clear();

        for(int i=0;i<n;i++)
        {
            int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
            Y.push_back(a-b); Y.push_back(a+b);
            Y.push_back(a);
            op.push_back(OP(a-b,a,(100-c)/100.0,1));
            op.push_back(OP(a,a+b,(100-d)/100.0,0));
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&B[i],&Z[i]);
            Y.push_back(B[i]);
        }
        sort(Y.begin(),Y.end());
        Y.erase(unique(Y.begin(),Y.end()),Y.end());
        for(int i=0;i<(int)Y.size();i++) H[Y[i]]=i;

        seg.build(0,(int)Y.size(),1);
        for(int i=0;i<(int)op.size();i++)
        {
            if(op[i].lft) seg.updata(H[op[i].st],H[op[i].ed]-1,1,op[i].flag);
            else seg.updata(H[op[i].st]+1,H[op[i].ed],1,op[i].flag);
        }
        double res=0;
        for(int i=0;i<m;i++)
        {
            res+=Z[i]*seg.query(H[B[i]],1);
        }
        printf("%.4lf\n",res);
    }
    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p2.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x-T[p1.x].h<T[p2.x].x-T[p2.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*(p[T[i].no]*q[T[i].no]+(1-p[T[i].no])*(1-q[T[i].no])));
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p1.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x+T[p1.x].h<T[p2.x].x+T[p1.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p1.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x+T[p1.x].h<T[p2.x].x+T[p1.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[i].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[i].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p2.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x-T[p1.x].h<T[p2.x].x-T[p2.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p1.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x+T[p1.x].h<T[p2.x].x+T[p1.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[i].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[i].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p2.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x+T[p1.x].h<T[p2.x].x+T[p2.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) (x&1)
#define debug(x) cout << #x << " => " << x << endl
typedef long long ll;
typedef long double ld;
const ll oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const int _cnt = 1000 * 1000;
const int _p = 1000 * 1000 * 1000 + 7;
//const int _p = 1007;
ll o(ll x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
//ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }
using namespace std;

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

struct treetype{
    int x,h,l,r,no;
    bool s;
};

treetype T[200005];

struct ptype{
    int x;
    ptype(){}
    ptype(int _x){x=_x;}
    friend bool operator < (const ptype & p1, const ptype & p2){
        return T[p1.x].x+T[p1.x].h>T[p2.x].x+T[p2.x].h;
    }
};

struct qtype{
    int x;
    qtype(){}
    qtype(int _x){x=_x;}
    friend bool operator < (const qtype & p1, const qtype & p2){
        return T[p1.x].x-T[p1.x].h<T[p2.x].x-T[p2.x].h;
    }
};

bool cmp(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s>t2.s);
}

bool cmp1(const treetype & t1, const treetype & t2){
    return (t1.x<t2.x) || (t1.x==t2.x && t1.s<t2.s);
}

priority_queue <ptype> Q;
priority_queue <qtype> W;
int n,m,cnt0=0;
double p[200005],P=1,q[200005],L=1,ans=0;

int main() {
    //file_put();

    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d%d%d%d",&T[i].x,&T[i].h,&T[i].l,&T[i].r);
        T[i].no=i;
        T[i].s=false;
    }
    for (int i=1; i<=m; i++) {
        scanf("%d%d",&T[n+i].x,&T[n+i].h);
        T[n+i].no=i;
        T[n+i].s=true;
    }
    sort(T+1,T+n+m+1,cmp);

    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) {
            Q.push(ptype(i));
            if (T[i].r==100) cnt0++; else P*=1-((double)T[i].r/100);
        }
        if (T[i].s) {
            while (!Q.empty() && T[Q.top().x].x+T[Q.top().x].h<T[i].x) {
                if (T[Q.top().x].r==100) cnt0--; else P/=1-((double)T[Q.top().x].r/100);
                Q.pop();
            }
            if (!cnt0) p[T[i].no]=P; else p[T[i].no]=0;
        }
    }
    sort(T+1,T+n+m+1,cmp1);
    cnt0=0;
    for (int i=n+m; i>=1; i--) {
        if (!T[i].s) {
            W.push(qtype(i));
            if (T[i].l==100) cnt0++; else L*=1-((double)T[i].l/100);
        }
        if (T[i].s) {
            while (!W.empty() && T[W.top().x].x-T[W.top().x].h>T[i].x) {
                if (T[W.top().x].l==100) cnt0--; else L/=1-((double)T[W.top().x].l/100);
                W.pop();
            }
            if (!cnt0) q[T[i].no]=L; else q[T[i].no]=0;
        }
    }
    for (int i=1; i<=n+m; i++) {
        if (!T[i].s) continue;
        ans+=(T[i].h*p[T[i].no]*q[T[i].no]);
    }
    printf("%.12lf\n",ans);

    return 0;
}


//lxrtxdy!
#include <bits/stdc++.h>
#define ls o*2
#define rs o*2+1
using namespace std;
const int N = 5e5+7;
double L[100010],R[100010];
int A[100010],h[100010],B[N],C[10010],D[10010];
double O[N<<2],laz[N<<2];
void build(int o,int l,int r){
    laz[o]=1;
    if(l==r){O[o]=1;return;}
    int mid=l+(r-l)/2;
    build(ls,l,mid);
    build(rs,mid+1,r);
    O[o]=O[ls]+O[rs];
}
void pushdown(int o){
    if(laz[o]!=1){
        laz[ls]*=laz[o];
        laz[rs]*=laz[o];
        O[ls]*=laz[o];
        O[rs]*=laz[o];
        laz[o]=1;
    }
}
void update(int o,int l,int r,int x,int y,double p){
    if(x<=l&&r<=y){
        O[o]*=p;
        laz[o]*=p;
        return;
    }
    int mid=l+(r-l)/2;
    pushdown(o);
    if(x<=mid)update(ls,l,mid,x,y,p);
    if(y>mid)update(rs,mid+1,r,x,y,p);
    O[o]=O[ls]+O[rs];
}
double query(int o,int l,int r,int x){
    if(l==r)return O[o];
    int mid=l+(r-l)/2;
    pushdown(o);
    if(x<=mid)return query(ls,l,mid,x);
    else return query(rs,mid+1,r,x);
}
int main(){
    int n,m,c=0;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d %d %lf %lf",&A[i],&h[i],&L[i],&R[i]);
        L[i]/=100;R[i]/=100;
        B[++c]=A[i]-h[i];
        B[++c]=A[i]-1;
        B[++c]=A[i]+h[i];
        B[++c]=A[i]+1;
    }
    for(int i=1;i<=m;i++){
        scanf("%d %d",&C[i],&D[i]);
        B[++c]=C[i];
    }
    sort(B+1,B+1+c);
    int u=unique(B+1,B+1+c)-B-1;
    build(1,1,u);
    for(int i=1;i<=n;i++){
        int a=lower_bound(B+1,B+1+u,A[i]-h[i])-B;
        int b=lower_bound(B+1,B+1+u,A[i]-1)-B;
        update(1,1,u,a,b,1-L[i]);
        a=lower_bound(B+1,B+1+u,A[i]+1)-B;
        b=lower_bound(B+1,B+1+u,A[i]+h[i])-B;
        update(1,1,u,a,b,1-R[i]);
    }
    double ans=0;
    for(int i=1;i<=m;i++){
        int a=lower_bound(B+1,B+1+u,C[i])-B;
        double p=query(1,1,u,a);
        ans+=p*D[i];
    }
    printf("%f\n",ans);
}

	  	  			 								      	 			 	//hellobig_tq
//orzlxr!//hello


#include <bits/stdc++.h>

#define task "E"
#define all(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define Rep(i, r, l) for (int i = (r); i >= (l); --i)
#define DB(X) { cerr << #X << " = " << (X) << '\n'; }
#define DB1(A, _) { cerr << #A << "[" << _ << "] = " << (A[_]) << '\n'; }
#define DB2(A, _, __) { cerr << #A << "[" << _ << "][" << __ << "] = " << (A[_][__]) << '\n'; }
#define DB3(A, _, __, ___) { cerr << #A << "[" << _ << "][" << __ << "][" << ___ << "] = " << (A[_][__][___]) << '\n'; }
#define PR(A, l, r) { cerr << '\n'; rep(_, l, r) DB1(A, _); cerr << '\n';}
#define SZ(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back
#define pf push_front
#define F first
#define S second
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; } // sort(arr, arr + N, by(a));
#define next ___next
#define prev ___prev
#define y1 ___y1
#define left ___left
#define right ___right
#define y0 ___y0
#define div ___div
#define j0 ___j0
#define jn ___jn

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using namespace std;
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vl;
const int N = 1e5 + 2;
ii mush[10003];
struct IT
{
    vector<ld> it, lz;
    IT(int n) {it.assign(n + 1, 0); lz.assign(4 * n, 1);}
    void build(int id, int l, int r)
    {
        if (l == r)
        {
            it[l] = mush[l].S;
            return;
        }
        int m = (l + r) >> 1;
        build(id << 1, l, m);
        build((id << 1) | 1, m + 1, r);
    }
    void dolazy(int id, int l, int r)
    {
        if (lz[id] == 1) return;
        if (l == r) it[l] *= lz[id];
        else
        {
            lz[id << 1] *= lz[id];
            lz[(id << 1) | 1] *= lz[id];
        }
        lz[id] = 1;
    }
    void update(int id, int l, int r, int L, int R, int p)
    {
        dolazy(id, l, r);
        if (l > R || r < L || L > R) return;
        if (L <= l && r <= R)
        {
            lz[id] *= p / 100.0;
            dolazy(id, l, r);
            return;
        }
        int m = (l + r) >> 1;
        update(id << 1, l, m, L, R, p);
        update((id << 1) | 1, m + 1, r, L, R, p);
    }
    void cal(int id, int l, int r)
    {
        dolazy(id, l, r);
        if (l == r) return;
        int m = (l + r) >> 1;
        cal(id << 1, l, m);
        cal((id << 1) | 1, m + 1, r);
    }
};
int n, m, a[N], h[N], pr[N], pl[N];

int main()
{
#ifdef HynDuf
    freopen(task".in", "r", stdin);
    //freopen(task".out", "w", stdout);
#else
    ios_base::sync_with_stdio(false); cin.tie(nullptr);
#endif
    cin >> n >> m;
    rep(i, 1, n) cin >> a[i] >> h[i] >> pl[i] >> pr[i];
    rep(i, 1, m) cin >> mush[i].F >> mush[i].S;
    sort(mush + 1, mush + 1 + m);
    IT seg(m);
    seg.build(1, 1, m);
    rep(i, 1, n)
    {
        int l = lower_bound(mush + 1, mush + 1 + m, ii(a[i] - h[i], -1)) - mush;
        int r = lower_bound(mush + 1, mush + 1 + m, ii(a[i], -1)) - mush - 1;
        seg.update(1, 1, m, l, r, (100 - pl[i]));

        l = upper_bound(mush + 1, mush + 1 + m, ii(a[i], 1e9)) - mush;
        r = upper_bound(mush + 1, mush + 1 + m, ii(a[i] + h[i], 1e9)) - mush - 1;
        seg.update(1, 1, m, l, r, (100 - pr[i]));
    }
    seg.cal(1, 1, m);
    ld ans = 0;
    rep(i, 1, m) ans += seg.it[i];
    cout << fixed << setprecision(10) << ans;
    return 0;
}


#include <bits/stdc++.h>

#define task "E"
#define all(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define Rep(i, r, l) for (int i = (r); i >= (l); --i)
#define DB(X) { cerr << #X << " = " << (X) << '\n'; }
#define DB1(A, _) { cerr << #A << "[" << _ << "] = " << (A[_]) << '\n'; }
#define DB2(A, _, __) { cerr << #A << "[" << _ << "][" << __ << "] = " << (A[_][__]) << '\n'; }
#define DB3(A, _, __, ___) { cerr << #A << "[" << _ << "][" << __ << "][" << ___ << "] = " << (A[_][__][___]) << '\n'; }
#define PR(A, l, r) { cerr << '\n'; rep(_, l, r) DB1(A, _); cerr << '\n';}
#define SZ(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back
#define pf push_front
#define F first
#define S second
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; } // sort(arr, arr + N, by(a));
#define next ___next
#define prev ___prev
#define y1 ___y1
#define left ___left
#define right ___right
#define y0 ___y0
#define div ___div
#define j0 ___j0
#define jn ___jn

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using namespace std;
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vl;
const int N = 1e5 + 2;
ii mush[10003];
struct IT
{
    vector<ld> it, lz;
    IT(int n) {it.assign(n + 1, 0); lz.assign(4 * n, 1);}
    void build(int id, int l, int r)
    {
        if (l == r)
        {
            it[l] = mush[l].S;
            return;
        }
        int m = (l + r) >> 1;
        build(id << 1, l, m);
        build((id << 1) | 1, m + 1, r);
    }
    void dolazy(int id, int l, int r)
    {
        if (lz[id] == 1) return;
        if (l == r) it[l] *= lz[id];
        else
        {
            lz[id << 1] *= lz[id];
            lz[(id << 1) | 1] *= lz[id];
        }
        lz[id] = 1;
    }
    void update(int id, int l, int r, int L, int R, int p)
    {
        dolazy(id, l, r);
        if (l > R || r < L || L > R) return;
        if (L <= l && r <= R)
        {
            lz[id] *= p / 100.0;
            dolazy(id, l, r);
            return;
        }
        int m = (l + r) >> 1;
        update(id << 1, l, m, L, R, p);
        update((id << 1) | 1, m + 1, r, L, R, p);
    }
    void cal(int id, int l, int r)
    {
        dolazy(id, l, r);
        if (l == r) return;
        int m = (l + r) >> 1;
        cal(id << 1, l, m);
        cal((id << 1) | 1, m + 1, r);
    }
};
int n, m, a[N], h[N], pr[N], pl[N];

int main()
{
#ifdef HynDuf
    freopen(task".in", "r", stdin);
    //freopen(task".out", "w", stdout);
#else
    ios_base::sync_with_stdio(false); cin.tie(nullptr);
#endif
    cin >> n >> m;
    rep(i, 1, n) cin >> a[i] >> h[i] >> pl[i] >> pr[i];
    rep(i, 1, m) cin >> mush[i].F >> mush[i].S;
    sort(mush + 1, mush + 1 + m);
    IT seg(m);
    seg.build(1, 1, m);
    rep(i, 1, n)
    {
        int l = lower_bound(mush + 1, mush + 1 + m, ii(a[i] - h[i], -1)) - mush;
        int r = lower_bound(mush + 1, mush + 1 + m, ii(a[i], -1)) - mush - 1;
        seg.update(1, 1, m, l, r, (100 - pl[i]));

        l = upper_bound(mush + 1, mush + 1 + m, ii(a[i], 1e9)) - mush;
        r = upper_bound(mush + 1, mush + 1 + m, ii(a[i] + h[i], 1e9)) - mush - 1;
        seg.update(1, 1, m, l, r, (100 - pr[i]));
    }
    seg.cal(1, 1, m);
    ld ans = 0;
    rep(i, 1, m) ans += mush[i].S * seg.it[i];
    cout << fixed << setprecision(10) << ans;
    return 0;
}


//lxrtxdy!
#include <bits/stdc++.h>
#define ls o*2
#define rs o*2+1
using namespace std;
const int N = 5e5+7;
double L[100010],R[100010];
int A[100010],h[100010],B[N],C[10010],D[10010];
double O[N<<2],laz[N<<2];
void build(int o,int l,int r){
    laz[o]=1;
    if(l==r){O[o]=1;return;}
    int mid=l+(r-l)/2;
    build(ls,l,mid);
    build(rs,mid+1,r);
    O[o]=O[ls]+O[rs];
}
void pushdown(int o){
    if(laz[o]!=1){
        laz[ls]*=laz[o];
        laz[rs]*=laz[o];
        O[ls]*=laz[o];
        O[rs]*=laz[o];
        laz[o]=1;
    }
}
void update(int o,int l,int r,int x,int y,double p){
    if(x<=l&&r<=y){
        O[o]*=p;
        laz[o]*=p;
        return;
    }
    int mid=l+(r-l)/2;
    pushdown(o);
    if(x<=mid)update(ls,l,mid,x,y,p);
    if(y>mid)update(rs,mid+1,r,x,y,p);
    O[o]=O[ls]+O[rs];
}
double query(int o,int l,int r,int x){
    if(l==r)return O[o];
    int mid=l+(r-l)/2;
    pushdown(o);
    if(x<=mid)return query(ls,l,mid,x);
    else return query(rs,mid+1,r,x);
}
int main(){
    int n,m,c=0;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d %d %lf %lf",&A[i],&h[i],&L[i],&R[i]);
        L[i]/=100;R[i]/=100;
        B[++c]=A[i]-h[i];
        B[++c]=A[i]-1;
        B[++c]=A[i]+h[i];
        B[++c]=A[i]+1;
    }
    for(int i=1;i<=m;i++){
        scanf("%d %d",&C[i],&D[i]);
        B[++c]=C[i];
    }
    sort(B+1,B+1+c);
    int u=unique(B+1,B+1+c)-B-1;
    build(1,1,u);
    for(int i=1;i<=n;i++){
        int a=lower_bound(B+1,B+1+u,A[i]-h[i])-B;
        int b=lower_bound(B+1,B+1+u,A[i]-1)-B;
        update(1,1,u,a,b,1-L[i]);
        a=lower_bound(B+1,B+1+u,A[i]+1)-B;
        b=lower_bound(B+1,B+1+u,A[i]+h[i])-B;
        update(1,1,u,a,b,1-R[i]);
    }
    double ans=0;
    for(int i=1;i<=m;i++){
        int a=lower_bound(B+1,B+1+u,C[i])-B;
        double p=query(1,1,u,a);
        ans+=p*D[i];
    }
    printf("%f\n",ans);
}

	  	  			 								      	 			 	//hellobig_tq
//orzlxr!//hello//hello


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*10],flg[maxn*10];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+cnt);
	cnt=unique(A+1,A+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,req[i].l/100.0);
		update(1,1,cnt,staR,endR,req[i].r/100.0);
	}
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*query(1,1,cnt,upper_bound(A+1,A+cnt,rem[i].b)-A-1);
	printf("%.5lf\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*10],flg[maxn*10];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	//cout<<v<<endl;
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+cnt);
	cnt=unique(A+1,A+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,1-req[i].l/100.0);
		update(1,1,cnt,staR,endR,1-req[i].r/100.0);
	}
	/*
	1 1
	3 2 73 12
	1 5
	*/
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*(query(1,1,cnt,upper_bound(A+1,A+cnt,rem[i].b)-A-1));
	printf("%.5lf\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*10],flg[maxn*10];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+1+cnt);
	cnt=unique(A+1,A+1+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+1+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+1+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+1+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+1+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,req[i].l/100.0);
		update(1,1,cnt,staR,endR,req[i].r/100.0);
	}
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*query(1,1,cnt,upper_bound(A+1,A+1+cnt,rem[i].b)-A-1);
	printf("%.5lf\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*10],flg[maxn*10];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	//cout<<v<<endl;
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+cnt);
	cnt=unique(A+1,A+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,req[i].l/100.0);
		update(1,1,cnt,staR,endR,req[i].r/100.0);
	}
	/*
	1 1
	3 2 73 12
	1 5
	*/
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*(1-query(1,1,cnt,upper_bound(A+1,A+cnt,rem[i].b)-A-1));
	printf("%.5lf\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*15],flg[maxn*15];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	//cout<<v<<endl;
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+1+cnt);
	cnt=unique(A+1,A+1+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+1+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+1+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+1+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+1+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,1-req[i].l/100.0);
		update(1,1,cnt,staR,endR,1-req[i].r/100.0);
	}
	/*
	1 1
	3 2 73 12
	1 5
	*/
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*(query(1,1,cnt,upper_bound(A+1,A+1+cnt,rem[i].b)-A-1));
	printf("%.5lf\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100100;
int n,m;
double tr[maxn*10],flg[maxn*10];
struct {
	int a,h;
	double l,r;
}req[maxn];
struct {
	int b,z;
}rem[maxn];
int A[maxn*5];
void build(int t,int l,int r){
	flg[t]=tr[t]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	build(t<<1,l,mid);
	build(t<<1|1,mid+1,r);
}
void pushdown(int t){
	if(fabs(flg[t]-1)>1e-5){
		flg[t<<1]*=flg[t];
		flg[t<<1|1]*=flg[t];
		tr[t<<1]*=flg[t];
		tr[t<<1|1]*=flg[t];
		flg[t]=1;
	}
}
void update(int t,int l,int r,int L,int R,double v){
	//cout<<v<<endl;
	if(L<=l&&r<=R){
		flg[t]*=v;
		tr[t]*=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=L)update(t<<1,l,mid,L,R,v);
	if(mid<R)update(t<<1|1,mid+1,r,L,R,v);
}
double query(int t,int l,int r,int pos){
	if(l==r)return tr[t];
	int mid=(l+r)>>1;
	pushdown(t);
	if(mid>=pos)return query(t<<1,l,mid,pos);
	return query(t<<1|1,mid+1,r,pos);
}
int main(){
	scanf("%d%d",&n,&m);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%lf%lf",&req[i].a,&req[i].h,&req[i].l,&req[i].r);
		A[++cnt]=req[i].a-1;
		A[++cnt]=req[i].a+1;
		A[++cnt]=req[i].a-req[i].h;
		A[++cnt]=req[i].a+req[i].h;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&rem[i].b,&rem[i].z);
		A[++cnt]=rem[i].b;
	}
	sort(A+1,A+1+cnt);
	cnt=unique(A+1,A+1+cnt)-A-1;
	build(1,1,cnt);
	for(int i=1;i<=n;i++){
		int staL=upper_bound(A+1,A+1+cnt,req[i].a-req[i].h)-A-1;
		int endL=upper_bound(A+1,A+1+cnt,req[i].a-1)-A-1;
		int staR=upper_bound(A+1,A+1+cnt,req[i].a+1)-A-1;
		int endR=upper_bound(A+1,A+1+cnt,req[i].a+req[i].h)-A-1;
		//cout<<staL<<" "<<endL<<" "<<staR<<" "<<endR<<endl;
		update(1,1,cnt,staL,endL,1-req[i].l/100.0);
		update(1,1,cnt,staR,endR,1-req[i].r/100.0);
	}
	/*
	1 1
	3 2 73 12
	1 5
	*/
	double ans=0;
	for(int i=1;i<=m;i++)ans+=1.0*rem[i].z*(query(1,1,cnt,upper_bound(A+1,A+1+cnt,rem[i].b)-A-1));
	printf("%.5lf\n",ans);
}


#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int MAXN = (int) 1e5 + 5;
const int MAXM = (int) 1e4 + 5;
const double eps = 1e-6;

struct segTreeNode {
    double data;
    double mark;
    int start;
    int end;

    segTreeNode *left;
    segTreeNode *right;

    segTreeNode(double d, double m, int s, int e, segTreeNode *l = NULL, segTreeNode *r = NULL) {
        data = d;
        mark = m;
        start = s;
        end = e;
        left = l;
        right = r;
    }

    segTreeNode() {
        data = 0;
        mark = 1;
    }
};

segTreeNode *build(const int a[], int start, int end) {
    if (start == end) {
        segTreeNode *root = new segTreeNode(a[start], 1, start, end);
        return root;
    }
    segTreeNode *root = new segTreeNode();
    int mid = (start + end) >> 1;
    root->left = build(a, start, mid);
    root->right = build(a, mid + 1, end);
    root->data = root->left->data + root->right->data;
    root->start = start;
    root->end = end;
    return root;
}

double query(segTreeNode *root, int qstart, int qend) {
    if (qstart > root->end || qend < root->start) {
        return 0;
    }
    if (root->start >= qstart && root->end <= qend) {
        return root->data;
    }
    return query(root->left, qstart, qend) + query(root->right, qstart, qend);
}

void pushDown(segTreeNode *root) {
    if (root->mark - 1 > eps || root->mark - 1 < -eps) {
        root->left->mark *= root->mark;
        root->right->mark *= root->mark;
        root->left->data *= root->mark;
        root->right->data *= root->mark;
        root->mark = 1.0;
    }
}

void update(segTreeNode *root, int ustart, int uend, double frac) {
    if (ustart > root->end || uend < root->start) {
        return;
    }
    if (root->data == 0) {
        return;
    }
    if (ustart <= root->start && uend >= root->end) {
        root->data *= frac;
        root->mark *= frac;
        return;
    }
    pushDown(root);
    update(root->left, ustart, uend, frac);
    update(root->right, ustart, uend, frac);
    root->data = root->left->data + root->right->data;
}

void del(segTreeNode *root) {
    if (root == NULL)return;
    del(root->left);
    del(root->right);
    delete root;
}

int main() {
    int n, m;
    long long p[MAXN * 5];
    int line[MAXN * 5];
    long long a[MAXN];
    long long h[MAXN];
    int l[MAXN], r[MAXN];
    long long b[MAXM];
    int z[MAXM];
    while (scanf("%d%d", &n, &m) != EOF) {
        long long c = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%lld%lld%d%d", &a[i], &h[i], &l[i], &r[i]);
            p[c++] = a[i];
            p[c++] = a[i] - 1;
            p[c++] = a[i] + 1;
            p[c++] = a[i] - h[i];
            p[c++] = a[i] + h[i];
        }
        for (int i = 0; i < m; ++i) {
            scanf("%lld%d", &b[i], &z[i]);
            p[c++] = b[i];
        }
        sort(p, p + c);
        c = unique(p, p + c) - p;
        fill(line, line + c, 0);
        for (int i = 0; i < m; ++i) {
            int treePos = lower_bound(p, p + c, b[i]) - p;
            line[treePos] += z[i];
        }
        segTreeNode *root = build(line, 0, c - 1);
        for (int i = 0; i < n; ++i) {
            int left = lower_bound(p, p + c, a[i] - h[i]) - p;
            int right = lower_bound(p, p + c, a[i] - 1) - p;
            update(root, left, right, (100.0 - l[i]) / 100);
            left = lower_bound(p, p + c, a[i] + 1) - p;
            right = lower_bound(p, p + c, a[i] + h[i]) - p;
            update(root, left, right, (100.0 - r[i]) / 100);
        }
        printf("%lf\n", query(root, 0, c - 1));
        del(root);
    }
}