#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005, maxm = 10005, maxp = 4 * maxn + maxm;
int n, m;
struct Tree {
  int a, h, l, r;
  void input() { cin >> a >> h >> l >> r; }
} tree[maxn];
struct Coor {
  int x, pow;
  void reset(int ix, int ipow) {
    x = ix;
    pow = ipow;
  }
  void copyOf(const Coor &co) {
    x = co.x;
    pow = co.pow;
  }
  bool operator<(const Coor cmp) const { return x < cmp.x; }
};
struct HashTable {
  Coor val[maxp];
  int cnt;
  void reset() { cnt = 0; }
  void add(int x, int v) { val[cnt++].reset(x, v); }
  void init() {
    sort(val, val + cnt);
    int tCnt = 0;
    for (int i = 0; i < cnt; i++) {
      if (!i || val[i].x != val[i - 1].x)
        val[tCnt++].copyOf(val[i]);
      else
        val[tCnt - 1].pow += val[i].pow;
    }
    cnt = tCnt;
  }
  int get(int key) {
    int ll = 0, rr = cnt - 1, mid;
    while (ll < rr) {
      mid = (ll + rr) >> 1;
      if (val[mid].x > key)
        rr = mid;
      else if (val[mid].x < key)
        ll = mid + 1;
      else
        return mid;
    }
    return ll;
  }
} ht;
struct Node {
  Node *ls, *rs;
  double pow, lazy;
  int l, r;
};
struct SegmentTree {
  Node node[maxp << 2];
  Node *root;
  int cnt;
  Node *newNode() {
    node[cnt].lazy = 1.0;
    return &node[cnt++];
  }
  void init() {
    cnt = 0;
    root = newNode();
    init(root, 0, ht.cnt - 1);
  }
  void init(Node *rt, int l, int r) {
    rt->l = l;
    rt->r = r;
    if (l == r) {
      rt->pow = (double)ht.val[l].pow;
      return;
    }
    int mid = (l + r) >> 1;
    rt->ls = newNode();
    rt->rs = newNode();
    init(rt->ls, l, mid);
    init(rt->rs, mid + 1, r);
  }
  void pushDown(Node *rt) {
    if (rt->lazy != 1.0 && rt->l != rt->r) {
      rt->ls->lazy *= rt->lazy;
      rt->rs->lazy *= rt->lazy;
      rt->lazy = 1.0;
    }
  }
  void update(int l, int r, double pob) { update(root, l, r, pob); }
  void update(Node *rt, int l, int r, double pob) {
    if (l <= rt->l && r >= rt->r) {
      rt->lazy *= pob;
      if (rt->l == rt->r) {
        rt->pow *= rt->lazy;
        rt->lazy = 1.0;
      }
      return;
    }
    pushDown(rt);
    int mid = (rt->l + rt->r) >> 1;
    if (l <= mid) update(rt->ls, l, r, pob);
    if (r > mid) update(rt->rs, l, r, pob);
  }
  double query(int p) { return query(root, p); }
  double query(Node *rt, int p) {
    if (rt->l == rt->r) {
      rt->pow *= rt->lazy;
      return rt->pow;
    }
    pushDown(rt);
    int mid = (rt->l + rt->r) >> 1;
    if (p <= mid)
      return query(rt->ls, p);
    else
      return query(rt->rs, p);
  }
} st;
int main() {
  cin >> n >> m;
  ht.reset();
  for (int i = 0; i < n; i++) {
    tree[i].input();
    ht.add(tree[i].a - tree[i].h, 0);
    ht.add(tree[i].a - 1, 0);
    ht.add(tree[i].a + 1, 0);
    ht.add(tree[i].a + tree[i].h, 0);
  }
  for (int i = 0, b, p; i < m; i++) {
    cin >> b >> p;
    ht.add(b, p);
  }
  ht.init();
  st.init();
  for (int i = 0; i < n; i++) {
    st.update(ht.get(tree[i].a - tree[i].h), ht.get(tree[i].a - 1),
              (double)(100 - tree[i].l) / 100.0);
    st.update(ht.get(tree[i].a + 1), ht.get(tree[i].a + tree[i].h),
              (double)(100 - tree[i].r) / 100.0);
  }
  double res = 0;
  for (int i = 0; i < ht.cnt; i++)
    if (ht.val[i].pow != 0) {
      res += st.query(i);
    }
  printf("%.8f\n", res);
}
