#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sq(T a) {
  return a * a;
}
template <class T, class U>
inline void umin(T& a, U b) {
  if (a > b) a = b;
}
template <class T, class U>
inline void umax(T& a, U b) {
  if (a < b) a = b;
}
inline void print(int i) { printf("%d", i); }
inline void print(long long i) { printf("%I64d", i); }
inline void print(char a) { putchar(a); }
inline void print(string& a) { printf("%s", a.c_str()); }
template <class T, class... Args>
inline void print(T a, Args(... args)) {
  print(a), putchar(32), print(args...);
}
inline void scan(int& i) { scanf("%d", &i); }
inline void scan(long long& i) { scanf("%I64d", &i); }
inline void scan(char& a) { scanf(" %c", &a); }
inline void scan(string& a) {
  char c;
  while ((c = getchar()) <= 32 && c != EOF)
    ;
  for (; c != EOF && c > 32; c = getchar()) {
    a += c;
  }
}
inline int scanln(string& a) {
  a.clear();
  char c;
  while (c = getchar(), c != EOF && c < 32)
    ;
  for (; c != EOF && c >= 32; c = getchar()) {
    a += c;
  }
  if (c == 13) getchar();
  return c != EOF;
}
template <class T, class... Args>
inline void scan(T& a, Args(&... args)) {
  scan(a), scan(args...);
}
template <class T>
void operator+=(vector<T>& v, const T a) {
  v.push_back(a);
}
struct stripe {
  int n;
  vector<double> s;
  vector<double> lazy;
  stripe() {}
  stripe(int n) : n(n) {
    int off = 1;
    for (; off < n; off <<= 1)
      ;
    s = vector<double>(off * 2, 0);
    lazy = vector<double>(off * 2, 1);
  }
  inline void change(int a, double w) { change(a, w, 0, 0, n); }
  inline void change(int a, double w, int x, int le, int ri) {
    if (le + 1 == ri)
      s[x] += w;
    else {
      int me = (le + ri) / 2, L = x + x + 1, R = L + 1;
      if (a < me)
        change(a, w, L, le, me);
      else
        change(a, w, R, me, ri);
      s[x] += w;
    }
  }
  inline double fun(double a, double b) { return a + b; }
  inline void relax(int x, int le, int ri) {
    if (lazy[x] == 1) return;
    int me = (le + ri) / 2, L = x + x + 1, R = L + 1;
    if (le + 1 < ri) {
      lazy[L] *= lazy[x];
      lazy[R] *= lazy[x];
    }
    s[x] *= lazy[x];
    lazy[x] = 1;
  }
  inline double get(int a, int b) { return get(a, b, 0, 0, n); }
  inline double get(int a, int b, int x, int le, int ri) {
    relax(x, le, ri);
    if (b <= le || ri <= a) return 0;
    if (a <= le && ri <= b) return s[x];
    int me = (le + ri) / 2, L = x + x + 1, R = L + 1;
    return fun(get(a, b, L, le, me), get(a, b, R, me, ri));
  }
  inline void update(int a, int b, double w) { update(a, b, w, 0, 0, n); }
  inline void update(int a, int b, double w, int x, int le, int ri) {
    relax(x, le, ri);
    if (b <= le || ri <= a) return;
    if (a <= le && ri <= b) {
      lazy[x] = w;
      relax(x, le, ri);
      return;
    }
    int me = (le + ri) / 2, L = x + x + 1, R = L + 1;
    update(a, b, w, L, le, me);
    update(a, b, w, R, me, ri);
    s[x] = fun(s[L], s[R]);
  }
};
int n, m;
int x[100005], y[100005], l[100005], r[100005];
int b[10005], z[10005];
map<int, int> L;
int main() {
  scan(n, m);
  for (int i = 0; i < n; i++) {
    scan(x[i], y[i], l[i], r[i]);
  }
  for (int i = 0; i < m; i++) scan(b[i], z[i]);
  vector<int> w(b, b + m);
  sort((w).begin(), (w).end());
  w.resize(unique((w).begin(), (w).end()) - w.begin());
  for (int i = 0; i < (int(w.size())); i++) L[w[i]] = i;
  int k = (int(w.size()));
  stripe st(k);
  for (int i = 0; i < m; i++) {
    st.change(L[b[i]], z[i]);
  }
  for (int i = 0; i < n; i++) {
    int u = lower_bound((w).begin(), (w).end(), x[i] - y[i]) - w.begin();
    int v = lower_bound((w).begin(), (w).end(), x[i]) - w.begin();
    st.update(u, v, 1 - l[i] / 100.0);
    u = upper_bound((w).begin(), (w).end(), x[i]) - w.begin();
    v = upper_bound((w).begin(), (w).end(), x[i] + y[i]) - w.begin();
    st.update(u, v, 1 - r[i] / 100.0);
  }
  double ans = st.get(0, k);
  printf("%.8f\n", ans);
}
