#include <iostream>
#include <algorithm>
#include <vector>

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 vector<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;
}

inline int binSearch(const vector<long long> &a, long long val) {
    int mid;
    int l = 0, r = a.size() - 1;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (a[mid] == val) {
            return mid;
        } else if (a[mid] < val) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
}

int main() {
    int n, m;
    //long long p[MAXN << 4];
    //int line[MAXN << 4];
    vector<long long> p;

    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) {
        p.clear();
        for (int i = 0; i < n; ++i) {
            scanf("%lld%lld%d%d", &a[i], &h[i], &l[i], &r[i]);
            p.push_back(a[i]);
            p.push_back(a[i] + 1);
            p.push_back(a[i] - 1);
            p.push_back(a[i] - h[i]);
            p.push_back(a[i] + h[i]);
        }
        for (int i = 0; i < m; ++i) {
            scanf("%lld%d", &b[i], &z[i]);
            p.push_back(b[i]);
        }
        sort(p.begin(), p.end());
        int c = unique(p.begin(), p.end()) - p.begin();
        vector<int> line(c + 5, 0);
        for (int i = 0; i < m; ++i) {
            int treePos = binSearch(p, b[i]);
            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 left = binSearch(p, a[i] - h[i]);
            //int right = lower_bound(p, p + c, a[i] - 1) - p;
            int right = binSearch(p, a[i] - 1);
            update(root, left, right, (100.0 - l[i]) / 100);
            //left = lower_bound(p, p + c, a[i] + 1) - p;
            left = binSearch(p, a[i] + 1);
            //right = lower_bound(p, p + c, a[i] + h[i]) - p;
            right = binSearch(p, a[i] + h[i]);
            update(root, left, right, (100.0 - r[i]) / 100);
        }
        printf("%lf\n", query(root, 0, c - 1));
        del(root);
    }
}


#include <iostream>
#include <algorithm>

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;
}

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 (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;
}

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;
    }
    int mid = (root->start + root->end) >> 1;
    return query(root->left, root->start, mid) + query(root->right, mid + 1, root->end);
}

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));
    }
}


#include <iostream>
#include <algorithm>

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, end;

} segTree[MAXN * 5];

void build(int root, const int a[], int start, int end) {
    if (start == end) {
        segTree[root].data = a[start];
        segTree[root].mark = 1;
        segTree[root].start = segTree[root].end = start;
        return;
    }
    int mid = (start + end) >> 1;
    build(2 * root + 1, a, start, mid);
    build(2 * root + 2, a, mid + 1, end);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
    segTree[root].mark = 1;
    segTree[root].start = start;
    segTree[root].end = end;
}

double query(int root, int qstart, int qend) {
    if (qstart > segTree[root].end || qend < segTree[root].start) {
        return 0;
    }
    if (segTree[root].start >= qstart && segTree[root].end <= qend) {
        return segTree[root].data;
    }
    return query(2 * root + 1, qstart, qend) + query(2 * root + 2, qstart, qend);
}

inline void pushDown(int root) {
    if (segTree[root].mark > 1 + eps || segTree[root].mark < 1 - eps) {
        segTree[2 * root + 1].mark *= segTree[root].mark;
        segTree[2 * root + 2].mark *= segTree[root].mark;
        segTree[2 * root + 1].data *= segTree[root].mark;
        segTree[2 * root + 2].data *= segTree[root].mark;
        segTree[root].mark = 1;
    }
}

void update(int root, int ustart, int uend, double frac) {
    if (ustart > segTree[root].end || uend < segTree[root].start) {
        return;
    }
    if (ustart <= segTree[root].start && uend >= segTree[root].end) {
        segTree[root].data *= frac;
        segTree[root].mark *= frac;
        return;
    }
    pushDown(root);
    update(2 * root + 1, ustart, uend, frac);
    update(2 * root + 2, ustart, uend, frac);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
}

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;
        int root = 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];
        }
        build(root, 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));
    }
}


#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;
    }
    int mid = (root->start + root->end) >> 1;
    return query(root->left, root->start, mid) + query(root->right, mid + 1, root->end);
}

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);
    }
}


#include <iostream>
#include <algorithm>
#include <vector>

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 vector<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;
}

inline int binSearch(const vector<long long> &a, long long val, int start, int end) {
    int mid;
    int l = start, r = end;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (a[mid] == val) {
            return mid;
        } else if (a[mid] < val) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
}

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


#include <iostream>
#include <algorithm>

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, end;

} segTree[MAXN << 4];

void build(int root, const int a[], int start, int end) {
    if (start == end) {
        segTree[root].data = a[start];
        segTree[root].mark = 1;
        segTree[root].start = segTree[root].end = start;
        return;
    }
    int mid = (start + end) >> 1;
    build(2 * root + 1, a, start, mid);
    build(2 * root + 2, a, mid + 1, end);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
    segTree[root].mark = 1;
    segTree[root].start = start;
    segTree[root].end = end;
}

double query(int root, int qstart, int qend) {
    if (qstart > segTree[root].end || qend < segTree[root].start) {
        return 0;
    }
    if (segTree[root].start >= qstart && segTree[root].end <= qend) {
        return segTree[root].data;
    }
    return query(2 * root + 1, qstart, qend) + query(2 * root + 2, qstart, qend);
}

inline void pushDown(int root) {
    if (segTree[root].mark > 1 + eps || segTree[root].mark < 1 - eps) {
        segTree[2 * root + 1].mark *= segTree[root].mark;
        segTree[2 * root + 2].mark *= segTree[root].mark;
        segTree[2 * root + 1].data *= segTree[root].mark;
        segTree[2 * root + 2].data *= segTree[root].mark;
        segTree[root].mark = 1;
    }
}

void update(int root, int ustart, int uend, double frac) {
    if (ustart > segTree[root].end || uend < segTree[root].start) {
        return;
    }
    if (ustart <= segTree[root].start && uend >= segTree[root].end) {
        segTree[root].data *= frac;
        segTree[root].mark *= frac;
        return;
    }
    pushDown(root);
    update(2 * root + 1, ustart, uend, frac);
    update(2 * root + 2, ustart, uend, frac);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
}

int main() {
    int n, m;
    long long p[MAXN << 4];
    int line[MAXN << 4];
    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;
        int root = 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];
        }
        build(root, 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));
    }
}


#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;
}

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 (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;
}

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;
    }
    int mid = (root->start + root->end) >> 1;
    return query(root->left, root->start, mid) + query(root->right, mid + 1, root->end);
}

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);
        memset(line, 0, sizeof(line[0]) * c);
        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));
    }
}


#include <iostream>
#include <algorithm>

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, end;

} segTree[MAXN * 8];

void build(int root, const int a[], int start, int end) {
    if (start == end) {
        segTree[root].data = a[start];
        segTree[root].mark = 1;
        segTree[root].start = segTree[root].end = start;
        return;
    }
    int mid = (start + end) >> 1;
    build(2 * root + 1, a, start, mid);
    build(2 * root + 2, a, mid + 1, end);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
    segTree[root].mark = 1;
    segTree[root].start = start;
    segTree[root].end = end;
}

double query(int root, int qstart, int qend) {
    if (qstart > segTree[root].end || qend < segTree[root].start) {
        return 0;
    }
    if (segTree[root].start >= qstart && segTree[root].end <= qend) {
        return segTree[root].data;
    }
    return query(2 * root + 1, qstart, qend) + query(2 * root + 2, qstart, qend);
}

inline void pushDown(int root) {
    if (segTree[root].mark > 1 + eps || segTree[root].mark < 1 - eps) {
        segTree[2 * root + 1].mark *= segTree[root].mark;
        segTree[2 * root + 2].mark *= segTree[root].mark;
        segTree[2 * root + 1].data *= segTree[root].mark;
        segTree[2 * root + 2].data *= segTree[root].mark;
        segTree[root].mark = 1;
    }
}

void update(int root, int ustart, int uend, double frac) {
    if (ustart > segTree[root].end || uend < segTree[root].start) {
        return;
    }
    if (ustart <= segTree[root].start && uend >= segTree[root].end) {
        segTree[root].data *= frac;
        segTree[root].mark *= frac;
        return;
    }
    pushDown(root);
    update(2 * root + 1, ustart, uend, frac);
    update(2 * root + 2, ustart, uend, frac);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
}

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;
        int root = 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];
        }
        build(root, 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));
    }
}


#include <iostream>
#include <algorithm>

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;
}

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 (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;
}

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;
    }
    int mid = (root->start + root->end) >> 1;
    return query(root->left, root->start, mid) + query(root->right, mid + 1, root->end);
}

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));
    }
}


#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;
}

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 (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;
}

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;
    }
    int mid = (root->start + root->end) >> 1;
    return query(root->left, root->start, mid) + query(root->right, mid + 1, root->end);
}

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);
        //memset(line, 0, sizeof(line[0]) * c);
        for (int i = 0; i < m; ++i) {
            int treePos = lower_bound(p, p + c, b[i]) - p;
            line[treePos] += 1;
        }
        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);
        }
        double ans = 0;
        for (int i = 0; i < m; ++i) {
            int pos = lower_bound(p, p + c, b[i]) - p;
            ans += z[i] * query(root, pos, pos);
        }
        printf("%lf\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 << 4];
    int line[MAXN << 4];
    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);
    }
}


#include <iostream>
#include <algorithm>
#include <vector>

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 vector<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;
}

inline int binSearch(const vector<long long> &a, long long val, int start, int end) {
    int mid;
    int l = start, r = end;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (a[mid] == val) {
            return mid;
        } else if (a[mid] < val) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
}

int main() {
    int n, m;
    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) {
        vector<long long> p;
        for (int i = 0; i < n; ++i) {
            scanf("%lld%lld%d%d", &a[i], &h[i], &l[i], &r[i]);
            p.push_back(a[i]);
            p.push_back(a[i] + 1);
            p.push_back(a[i] - 1);
            p.push_back(a[i] - h[i]);
            p.push_back(a[i] + h[i]);
        }
        for (int i = 0; i < m; ++i) {
            scanf("%lld%d", &b[i], &z[i]);
            p.push_back(b[i]);
        }
        sort(p.begin(), p.end());
        int c = unique(p.begin(), p.end()) - p.begin();
        vector<int> line(c, 0);
        for (int i = 0; i < m; ++i) {
            int treePos = binSearch(p, b[i], 0, c - 1);
            line[treePos] += z[i];
        }
        segTreeNode *root = build(line, 0, c - 1);
        for (int i = 0; i < n; ++i) {
            int left = binSearch(p, a[i] - h[i], 0, c - 1);
            int right = binSearch(p, a[i] - 1, 0, c - 1);
            update(root, left, right, (100.0 - l[i]) / 100);
            left = binSearch(p, a[i] + 1, 0, c - 1);
            right = binSearch(p, a[i] + h[i], 0, c - 1);
            update(root, left, right, (100.0 - r[i]) / 100);
        }
        printf("%lf\n", query(root, 0, c - 1));
        del(root);
    }
}


#include <iostream>
#include <algorithm>

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, end;

} segTree[MAXN * 8];

void build(int root, const int a[], int start, int end) {
    if (start == end) {
        segTree[root].data = a[start];
        segTree[root].mark = 1;
        segTree[root].start = segTree[root].end = start;
        return;
    }
    int mid = (start + end) >> 1;
    build(2 * root + 1, a, start, mid);
    build(2 * root + 2, a, mid + 1, end);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
    segTree[root].mark = 1;
    segTree[root].start = start;
    segTree[root].end = end;
}

double query(int root, int qstart, int qend) {
    if (qstart > segTree[root].end || qend < segTree[root].start) {
        return 0;
    }
    if (segTree[root].start >= qstart && segTree[root].end <= qend) {
        return segTree[root].data;
    }
    return query(2 * root + 1, qstart, qend) + query(2 * root + 2, qstart, qend);
}

inline void pushDown(int root) {
    if (segTree[root].mark > 1 + eps || segTree[root].mark < 1 - eps) {
        segTree[2 * root + 1].mark *= segTree[root].mark;
        segTree[2 * root + 2].mark *= segTree[root].mark;
        segTree[2 * root + 1].data *= segTree[root].mark;
        segTree[2 * root + 2].data *= segTree[root].mark;
        segTree[root].mark = 1;
    }
}

void update(int root, int ustart, int uend, double frac) {
    if (ustart > segTree[root].end || uend < segTree[root].start) {
        return;
    }
    if (ustart <= segTree[root].start && uend >= segTree[root].end) {
        segTree[root].data *= frac;
        segTree[root].mark *= frac;
        return;
    }
    pushDown(root);
    update(2 * root + 1, ustart, uend, frac);
    update(2 * root + 2, ustart, uend, frac);
    segTree[root].data = segTree[2 * root + 1].data + segTree[2 * root + 2].data;
}

int main() {
    int n, m;
    long long p[MAXN * 8];
    int line[MAXN * 8];
    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;
        int root = 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];
        }
        build(root, 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));
    }
}


//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!


#include<bits/stdc++.h>
#define F first
#define S second
#define pii pair<int,int>
#define pb push_back
typedef long long ll;
typedef long double ld;
using namespace std;
const int N = 1e5 + 10 , M = 1e4 + 10 , INF = 1e9;
vector<ld> pm1[4 * N] , pm2[4 * N];
vector<pii> seg1[4 * N] , seg2[4 * N];
vector<int> X;

struct tr{
    int x , h , l , r;
};
tr a[N];

bool cmp(tr a,tr b){
    return a.x < b.x;
}

void build_1(int id , int s , int e){
    if(e - s < 2){
        int R = a[s].x + a[s].h , P = a[s].r;
        seg1[id].pb({R , 100 - P});
        pm1[id].pb(100 - P);
        return ;
    }
    int mid = (s + e)/2;
    build_1(2 * id , s , mid);
    build_1(2 * id + 1, mid , e);
    seg1[id].resize(e - s);
    pm1[id].resize(e - s);
    int len = e - s;
    merge(seg1[2*id].begin() , seg1[2*id].end() , seg1[2*id + 1].begin() , seg1[2*id + 1].end() , seg1[id].begin());
    for(int i=len-1;i>=0;i--){
        if(i + 1 == len )pm1[id][i] = seg1[id][i].S;
        else pm1[id][i] = pm1[id][i + 1] * seg1[id][i].S / (ld)100;
    }

    return ;
}

ld get_1(int id , int L , int R , int val , int s , int e){
    if(L<=s && e<=R){
        int ind = lower_bound(seg1[id].begin() , seg1[id].end() , pair<int,int> (val , -1)) - seg1[id].begin();
        if(ind == e-s)return (ld)100;
        return pm1[id][ind];
    }if(L>=e || s>=R)return (ld)100;
    int mid = (s + e)/2;
    return get_1(2*id , L , R , val , s , mid) * get_1(2*id + 1, L , R , val , mid , e) / (ld)100;
}

//

void build_2(int id , int s , int e){
    if(e - s < 2){
        int R = a[s].x - a[s].h , P = a[s].l;
        seg2[id].pb({R , 100 - P});
        pm2[id].pb(100 - P);
        return ;
    }
    int mid = (s + e)/2;
    build_2(2 * id , s , mid);
    build_2(2 * id + 1, mid , e);
    seg2[id].resize(e - s);
    pm2[id].resize(e - s);
    int len = e - s;
    merge(seg2[2*id].begin() , seg2[2*id].end() , seg2[2*id + 1].begin() , seg2[2*id + 1].end() , seg2[id].begin());
    for(int i=0;i<len;i++){
        if(i == 0)pm2[id][0] = seg2[id][i].S;
        else pm2[id][i] = pm2[id][i-1] * (seg2[id][i].S)/(ld)100;
    }
    return ;
}

ld get_2(int id , int L , int R , int val , int s , int e){
    if(L<=s && e<=R){
        int ind = upper_bound(seg2[id].begin() , seg2[id].end() , pair<int,int> (val , INF)) - seg2[id].begin();
        ind--;
        if(ind == -1)return (ld)100;
        return pm2[id][ind];
    }if(L>=e || s>=R)return (ld)100;
    int mid = (s + e)/2;
    return get_2(2*id , L , R , val , s , mid) * get_2(2*id + 1, L , R , val , mid , e) / (ld)100;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n , m; cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>a[i].x>>a[i].h>>a[i].l>>a[i].r;
        X.pb(a[i].x);
    }
    sort(a , a + n , cmp);
    sort(X.begin() , X.end());
    //for(int i=0;i<n;i++)cout<<a[i].x<<'\n';
    build_1(1 , 0 , n);
    build_2(1 , 0 , n);
    ld ANS = 0;
     for(int i=0;i<m;i++){
        int pos , z; cin>>pos>>z;
        ld ans1 = 100, ans2 = 100;
        int ind1 = lower_bound(X.begin() , X.end() , pos) - X.begin();
        if(ind1 != 0){
            ans1 = get_1(1 , 0 , ind1 , pos , 0 , n);
        }
        int ind2 = upper_bound(X.begin() , X.end() , pos) - X.begin();
        if(ind2 != n){
            ans2 = get_2(1 , ind2 , n , pos , 0 , n);
        }
        //cout<<ans1<<" "<<ans2<<endl;
        ld Good = ans1 * ans2 / (ld)100;
        Good = Good / (ld)100;
        ld x = Good * (ld)z;
        ANS += x;
     }
     cout<<fixed<<setprecision(10)<<ANS<<'\n';
}


//ITNOA
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
const long long INF=1e9+10,MAX=2e5+1e4,MOD=1e9+7,MAXL=25;
typedef long long ll;
typedef pair<ll,ll> pii;
typedef pair<pii,pii> piii;
void OUT(long double o,int x){
	 cout<<fixed<<setprecision(x)<<o;
	 return;
}
piii a[MAX];
pii b[MAX];
double seg[4*MAX];
int bsl(int s,int e,int k){
	if(s==e) return s;
	int m=(s+e)/2;
	if(b[m].F<k)	return bsl(m+1,e,k);
	return bsl(s,m,k);
}
int bsr(int s,int e,int k){
	if(s==e) return s;
	int m=((s+e)/2)+1;
	if(b[m].F>k) return bsr(s,m-1,k);
	return bsr(m,e,k);
}
void upd(int id,int b,int e,int l,int r,double x){
	if(e<=l||r<=b) return;
	if(l<=b&&e<=r){
		seg[id]*=x;
		return;
	}
	int m=(b+e)/2;
	upd(id*2,b,m,l,r,x);
	upd(id*2+1,m,e,l,r,x);
	return;
}
double geta(int id,int b,int e,int x){
	if(e-b==1) return seg[id];
	int m=(b+e)/2;
	if(x<m) return seg[id]*geta(id*2,b,m,x);
	return seg[id]*geta(id*2+1,m,e,x);
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	ll n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
		cin>>a[i].F.F>>a[i].F.S>>a[i].S.F>>a[i].S.S;
	for(int i=0;i<m;i++)
		cin>>b[i].F>>b[i].S;
	sort(a,a+n);
	sort(b,b+m);
	for(int i=0;i<=4*m;i++)
		seg[i]=1.0;
	for(int i=0;i<n;i++){
		ll l=bsl(0,m-1,a[i].F.F-a[i].F.S),r=bsr(0,m-1,a[i].F.F+a[i].F.S);
		ll ri=bsl(0,m-1,a[i].F.F+1),li=bsr(0,m-1,a[i].F.F-1);
		if(b[l].F<a[i].F.F&&b[l].F>=a[i].F.F-a[i].F.S)
			upd(1,0,m,l,li+1,((100-a[i].S.F)*1.0)/100.0);
		if(a[i].F.F<b[r].F&&b[r].F<=a[i].F.F+a[i].F.S)
			upd(1,0,m,ri,r+1,((100-a[i].S.S)*1.0)/100.0);
	}
	long double x=0.0;
	for(int i=0;i<m;i++)
		x+=geta(1,0,m,i)*b[i].S;
	cout<<fixed<<setprecision(6)<<x;
	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, (100 - l) / (ld) 100);
      E.emplace_back(1, a-h, (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, (100 - r) / (ld) 100);
      E.emplace_back(1, a+1, (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 = 1.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 += e.val * cur;
    }
  }

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

  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, (100 - l) / (ld) 100);
      E.emplace_back(1, a-h, (100 - l) / (ld) 100);
    }else
    {
      E.emplace_back(2, a-h, 0, 1);
      E.emplace_back(2, a-1, 0, -1);
    }
    if(r != 100)
    {
      E.emplace_back(0, a+h+1, (100 - r) / (ld) 100);
      E.emplace_back(1, a+1, (100 - r) / (ld) 100);
    }else
    {
      E.emplace_back(2, a+1, 0, 1);
      E.emplace_back(2, a+h, 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 = 1.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 += e.val * cur;
    }
  }

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

  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;
}


#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 - mushroom
  int x; // coordinate
  ld val; // val
  Event(){}
  Event(int t, int x, ld val)
    : t(t), x (x), val (val){}
  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);
    E.emplace_back(0, a, (100 - l) / (ld) 100);
    E.emplace_back(1, a-h, (100 - l) / (ld) 100);

    E.emplace_back(0, a+h+1, (100 - r) / (ld) 100);
    E.emplace_back(1, a+1, (100 - r) / (ld) 100);
  }
  for(int i=1;i<=m;++i)
  {
    int b, z;
    scanf("%d%d", &b, &z);
    E.emplace_back(2, b, z);
  }

  sort(E.begin(), E.end());
  ld cur = 1.0, ans = 0.0;
  for(auto e: E)
  {
    if(e.t == 0)
    {
      cur /= e.val;
    }else if(e.t == 1)
    {
      cur *= e.val;
    }else
    {
      ans += e.val * cur;
    }
  }

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

  return 0;
}


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

struct Mushroom
{
  int a, h, l, r;
};

typedef long double ld;

int main()
{
  int n, m;
  scanf("%d%d", &n, &m);
  vector<Mushroom> tree;
  for(int i=1;i<=n;++i)
  {
    int a, h, l , r;
    scanf("%d%d%d%d", &a, &h, &l, &r);
    tree.push_back({a, h, l, r});
  }
  //~ cerr << "fuck\n";
  ld ans = 0;
  for(int i=1;i<=m;++i)
  {
    int x, z;
    scanf("%d%d", &x, &z);
    //~ cerr << "mush " << x << ' ' << z << endl;
    ld rans = z;
    for(auto t : tree)
    {
      if( t.l > 0 && t.a - t.h <= x && x < t.a)
        rans *= (100 - t.l) / 100.0;

      if( t.r > 0 && t.a < x && x <= t.a + t.h)
        rans *= (100 - t.r) / 100.0;
    }
    //~ cerr << fixed << setprecision(3) << rans << endl;
    ans += rans;
  }
  cout << fixed << setprecision(12) << ans << endl;

  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;
}


#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("%f\n",res);
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=3e5+1e4+9;

int m,n;
int ia,ih,il,ir;
double z[10009];
int b[10009];
map<int,int> mp;
vector<int> ve;
struct qu{
double d;
int l,r;
bool lr;
};
vector<qu> q;
qu tmp;
double tag;

struct Segnode
{
	int tag;
	double value;
}tn[MAXN * 4];
int cl, cr;
void Inittree(int rt, int l, int r)
{
	tn[rt].tag=0;
	tn[rt].value=1.0;
	if(l == r)
	{
		return;
	}
	int mid = (l + r) >> 1;
	Inittree(rt * 2 + 1, l, mid);
	Inittree(rt * 2 + 2, mid + 1, r);
}
void update(int rt, int l, int r,double d)
{
	if(cl > r || cr < l)return;
	if(cl <= l && cr >= r)
	{
		tn[rt].tag=1;
		tn[rt].value*=d;
		return;
	}
	int mid = (l + r) >> 1;
	if(tn[rt].tag){
		tn[rt].tag=0;
		tn[rt*2+1].tag=1;
		tn[rt*2+1].value*=tn[rt].value;
		tn[rt*2+2].tag=1;
		tn[rt*2+2].value*=tn[rt].value;
		tn[rt].value=1.0;
	}
	update(rt * 2 + 1, l, mid,d);
	update(rt * 2 + 2, mid + 1, r,d);
}
double cnt(int rt, int l, int r)
{
	if(tn[rt].tag||l==r){
		return tn[rt].value;
	}
	if(tn[rt].tag){
		tn[rt].tag=0;
		tn[rt*2+1].tag=1;
		tn[rt*2+1].value*=tn[rt].value;
		tn[rt*2+2].tag=1;
		tn[rt*2+2].value*=tn[rt].value;
		tn[rt].value=1.0;
	}
	int mid = (l + r) >> 1;
	if(cl>mid){
		return cnt(rt * 2 + 2, mid + 1, r);
	}
	else{
		return cnt(rt * 2 + 1, l, mid);
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&ia,&ih,&il,&ir);
		ve.push_back(ia);
		ve.push_back(ia-ih);
		ve.push_back(ia+ih);
		qu tmp;
		tmp.lr=0;
		tmp.d=((double)100.0-il)/100.0;
		tmp.l=ia-ih;
		tmp.r=ia;
		q.push_back(tmp);
		tmp.lr=1;
		tmp.d=((double)100.0-ir)/100.0;
		tmp.l=ia;
		tmp.r=ia+ih;
		q.push_back(tmp);
	}
	for(int i=0;i<m;i++){
		scanf("%d%lf",&b[i],&z[i]);
		ve.push_back(b[i]);
	}
	sort(ve.begin(),ve.end());
	int id=0;
	for(int i=0;i<(int)ve.size();i++){
		if(ve[i]!=ve[i-1])mp[ve[i]]=id++;
	}
	Inittree(0,0,id);
	for(int i=0;i<(int)q.size();i++){
		if(q[i].lr){
			cl=mp[q[i].l]+1;
			cr=mp[q[i].r];
		}
		else{
			cl=mp[q[i].l];
			cr=mp[q[i].r]-1;
		}
		update(0,0,id,q[i].d);
	}
	double ans=0;
	for(int i=0;i<m;i++){
		cl=mp[b[i]];
		ans+=z[i]*cnt(0,0,id);
		//printf("%f\n",ans);
	}
	printf("%f\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=3e5+1e4+9;

int m,n;
int ia,ih,il,ir;
double z[10009];
int b[10009];
map<int,int> mp;
vector<int> ve;
struct qu{
double d;
int l,r;
bool lr;
};
vector<qu> q;
qu tmp;
double tag;

struct Segnode
{
	int tag;
	double value;
}tn[MAXN * 4];
int cl, cr;
void Inittree(int rt, int l, int r)
{
	tn[rt].tag=0;
	tn[rt].value=1.0;
	if(l == r)
	{
		return;
	}
	int mid = (l + r) >> 1;
	Inittree(rt * 2 + 1, l, mid);
	Inittree(rt * 2 + 2, mid + 1, r);
}
void update(int rt, int l, int r,double d)
{
	if(cl > r || cr < l)return;
	if(cl <= l && cr >= r)
	{
		tn[rt].tag=1;
		tn[rt].value*=d;
		return;
	}
	int mid = (l + r) >> 1;
	if(tn[rt].tag){
		tn[rt].tag=0;
		tn[rt*2+1].tag=1;
		tn[rt*2+1].value*=tn[rt].value;
		tn[rt*2+2].tag=1;
		tn[rt*2+2].value*=tn[rt].value;
		tn[rt].value=1.0;
	}
	update(rt * 2 + 1, l, mid,d);
	update(rt * 2 + 2, mid + 1, r,d);
}
double cnt(int rt, int l, int r)
{
	if(l==r){
		return tn[rt].value;
	}
	if(tn[rt].tag){
		tn[rt].tag=0;
		tn[rt*2+1].tag=1;
		tn[rt*2+1].value*=tn[rt].value;
		tn[rt*2+2].tag=1;
		tn[rt*2+2].value*=tn[rt].value;
		tn[rt].value=1.0;
	}
	int mid = (l + r) >> 1;
	if(cl>mid){
		return cnt(rt * 2 + 2, mid + 1, r);
	}
	else{
		return cnt(rt * 2 + 1, l, mid);
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&ia,&ih,&il,&ir);
		ve.push_back(ia);
		ve.push_back(ia-ih);
		ve.push_back(ia+ih);
		qu tmp;
		tmp.lr=0;
		tmp.d=((double)100.0-il)/100.0;
		tmp.l=ia-ih;
		tmp.r=ia;
		q.push_back(tmp);
		tmp.lr=1;
		tmp.d=((double)100.0-ir)/100.0;
		tmp.l=ia;
		tmp.r=ia+ih;
		q.push_back(tmp);
	}
	for(int i=0;i<m;i++){
		scanf("%d%lf",&b[i],&z[i]);
		ve.push_back(b[i]);
	}
	sort(ve.begin(),ve.end());
	int id=0;
	for(int i=0;i<(int)ve.size();i++){
		if(ve[i]!=ve[i-1])mp[ve[i]]=id++;
	}
	Inittree(0,0,id);
	for(int i=0;i<(int)q.size();i++){
		if(q[i].lr){
			cl=mp[q[i].l]+1;
			cr=mp[q[i].r];
		}
		else{
			cl=mp[q[i].l];
			cr=mp[q[i].r]-1;
		}
		update(0,0,id,q[i].d);
	}
	double ans=0;
	for(int i=0;i<m;i++){
		cl=mp[b[i]];
		ans+=z[i]*cnt(0,0,id);
		//printf("%f\n",ans);
	}
	printf("%f\n",ans);
	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 <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=3e5+1e4+9;

int m,n;
int ia,ih,il,ir;
double z[10009];
int b[10009];
map<int,int> mp;
vector<int> ve;
struct qu{
double d;
int l,r;
bool lr;
};
vector<qu> q;
qu tmp;
double tag;

struct Segnode
{
	int tag;
	double value;
}tn[MAXN * 4];
int cl, cr;
void Inittree(int rt, int l, int r)
{
	tn[rt].tag=0;
	tn[rt].value=1.0;
	if(l == r)
	{
		return;
	}
	int mid = (l + r) >> 1;
	Inittree(rt * 2 + 1, l, mid);
	Inittree(rt * 2 + 2, mid + 1, r);
}
void update(int rt, int l, int r,double d)
{
	if(cl > r || cr < l)return;
	if(cl <= l && cr >= r)
	{
		tn[rt].tag=1;
		tn[rt].value*=d;
		return;
	}
	int mid = (l + r) >> 1;
	if(tn[rt].tag){
		tn[rt].tag=0;
		tn[rt*2+1].tag=1;
		tn[rt*2+1].value*=tn[rt].value;
		tn[rt*2+2].tag=1;
		tn[rt*2+2].value*=tn[rt].value;
		tn[rt].value=1;
	}
	update(rt * 2 + 1, l, mid,d);
	update(rt * 2 + 2, mid + 1, r,d);
}
double cnt(int rt, int l, int r)
{
	if(tn[rt].tag){
		return tn[rt].value;
	}

	int mid = (l + r) >> 1;
	if(cl>mid){
		return cnt(rt * 2 + 2, mid + 1, r);
	}
	else{
		return cnt(rt * 2 + 1, l, mid);
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&ia,&ih,&il,&ir);
		ve.push_back(ia);
		ve.push_back(ia-ih);
		ve.push_back(ia+ih);
		qu tmp;
		tmp.lr=0;
		tmp.d=((double)100.0-il)/100.0;
		tmp.l=ia-ih;
		tmp.r=ia;
		q.push_back(tmp);
		tmp.lr=1;
		tmp.d=((double)100.0-ir)/100.0;
		tmp.l=ia;
		tmp.r=ia+ih;
		q.push_back(tmp);
	}
	for(int i=0;i<m;i++){
		scanf("%d%lf",&b[i],&z[i]);
		ve.push_back(b[i]);
	}
	sort(ve.begin(),ve.end());
	int id=0;
	for(int i=0;i<(int)ve.size();i++){
		if(ve[i]!=ve[i-1])mp[ve[i]]=id++;
	}
	Inittree(0,0,id);
	for(int i=0;i<(int)q.size();i++){
		if(q[i].lr){
			cl=mp[q[i].l]+1;
			cr=mp[q[i].r];
		}
		else{
			cl=mp[q[i].l];
			cr=mp[q[i].r]-1;
		}
		update(0,0,id,q[i].d);
	}
	double ans=0;
	for(int i=0;i<m;i++){
		cl=mp[b[i]];
		ans+=z[i]*cnt(0,0,id);
		//printf("%f\n",ans);
	}
	printf("%f\n",ans);
	return 0;
}


/*题意：有n棵树，m个蘑菇，每棵树有坐标a，高度h，向左边倒的概率，
向右的概率（概率用0-100表示），向左倒范围[x-h,x)内的蘑菇被破坏，
向右倒范围(x,x+h]范围内的蘑菇被破坏。每个蘑菇有坐标b，及它的魔力值z。
问树倒下后，所以蘑菇的魔力值的和的期望。离散化之后，成段更新，
即树倒下范围内的区间全部乘以倒向这边的概率。
最后遍历每个蘑菇的存活的概率乘以它的魔力值就可以了。*/
#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 <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


#include<bits/stdc++.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1|1
typedef long long ll;
const ll N = 3e5+55;
const ll mod = 1000000007;
double add[N<<2],sum[N<<2];
struct node{
    int pos,h,l,r;
}a[N];
map<int,int>b;
vector<int>v,v2;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
int get_id(int x){return upper_bound(v.begin(),v.end(),x)-v.begin()+1;}
int getid2(int x){return lower_bound(v2.begin(),v2.end(),x)-v2.begin()+1;}
void PushUp(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m,int l,int r){
    if (fabs(add[rt]-1)>0.00001){
        add[rt<<1]*=add[rt];
        add[rt<<1|1]*=add[rt];
        sum[rt<<1]*=add[rt];
        sum[rt<<1|1]*=add[rt];
        //printf("l:%d r:%d m:%d\n",l,r,m);
        //printf("lef:%f rig:%f\n",sum[rt<<1]);
        add[rt] = 1;
    }
}
void build(int l,int r,int rt){
    add[rt] = 1;
    sum[rt] = 0;
    if (l == r) {
        if(v2[getid2(v[l-1])-1]==v[l-1]){
            sum[rt]=b[v[l-1]];
            //printf("l:%d\n",l);
        }
        else
            sum[rt]=0;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void upedit(int L,int R,double c,int l,int r,int rt){
    if (L <= l && r <= R) {
        add[rt]*=c;
        sum[rt]*=c;
        return ;
    }
    int m = (l + r)>>1;
    PushDown(rt,m,l,r);
    if (L <= m)
        upedit(L, R, c, lson);
    if (m < R)
        upedit(L, R, c, rson);
    PushUp(rt);
}
double query(int L,int R,int l,int r,int rt){
    if (L <= l && r <= R) {
        //printf("%d %d %f\n",l,r,sum[rt]);
        return sum[rt];
    }
    int m = (l + r) >> 1;
    PushDown(rt,m,l,r);
    double ret = 0;
    if (L <= m)
        ret += query(L, R, lson);
    if (m < R)
        ret += query(L, R, rson);
    return ret;
}
int main(){
    ios::sync_with_stdio(false), cin.tie(0);
    int n,m,k,kk;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i].pos>>a[i].h>>a[i].l>>a[i].r;
        v.push_back(a[i].pos);
        v.push_back(a[i].pos+a[i].h);
        v.push_back(a[i].pos-a[i].h);
    }
    for(int i=1;i<=m;i++){
        cin>>k>>kk,v.push_back(k),v2.push_back(k);
        b[k]+=kk;
    }
    sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    sort(v2.begin(),v2.end()),v2.erase(unique(v2.begin(),v2.end()),v2.end());
    int sz=v.size();
    build(1,sz,1);
    //printf("%.5f\n",sum[1]);
    for(int i=1;i<=n;i++){
        int L=getid(a[i].pos-a[i].h);
        int R=get_id(a[i].pos+a[i].h)-1;
        int M=getid(a[i].pos);

        if(L<M){
            //printf("%d %d %f\n",L,M-1,1-a[i].l*1.0/100);
            upedit(L,M-1,1-a[i].l*1.0/100,1,sz,1);
            //printf("%.5f %.5f\n",query(5,5,1,sz,1),query(7,7,1,sz,1));
        }
        if(R>M){
            //printf("%d %d %f\n",M+1,R,1-a[i].r*1.0/100);
            upedit(M+1,R,1-a[i].r*1.0/100,1,sz,1);
            //printf("%.5f %.5f\n",query(5,5,1,sz,1),query(7,7,1,sz,1));
        }

    }
    printf("%.5f\n",sum[1]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1|1
typedef long long ll;
const ll N = 1e5+55;
const ll mod = 1000000007;
double add[N<<2],sum[N<<2];
struct node{
    int pos,h,l,r;
}a[N];
struct node2{
    int pos,val;
    bool friend operator < (node2 a,node2 b){
        return a.pos<b.pos;
    }
}b[N];
vector<int>v;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
void PushUp(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m,int l,int r){
    if (fabs(add[rt])>0.00001){
        if(fabs(add[rt<<1])<0.00001)
            add[rt<<1]=add[rt];
        else
            add[rt<<1]*=add[rt];
        if(fabs(add[rt<<1|1])<0.00001)
            add[rt<<1|1]=add[rt];
        else
            add[rt<<1|1]*=add[rt];
        sum[rt<<1]*=add[rt];
        sum[rt<<1|1]*=add[rt];
        //printf("l:%d r:%d m:%d\n",l,r,m);
        //printf("lef:%f rig:%f\n",sum[rt<<1]);
        add[rt] = 0;
    }
}
void build(int l,int r,int rt){
    add[rt] = 0;
    sum[rt] = 0;
    if (l == r) {
        sum[rt]=b[l].val;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void upedit(int L,int R,double c,int l,int r,int rt){
    if (L <= l && r <= R) {
        if(fabs(add[rt]-0)<0.00001)
            add[rt]=c;
        sum[rt]*=c;
        return ;
    }
    int m = (l + r)>>1;
    PushDown(rt,m,l,r);
    if (L <= m)
        upedit(L, R, c, lson);
    if (m < R)
        upedit(L, R, c, rson);
    PushUp(rt);
}
double query(int L,int R,int l,int r,int rt){
    if (L <= l && r <= R) {
        //printf("%d %d %f\n",l,r,sum[rt]);
        return sum[rt];
    }
    int m = (l + r) >> 1;
    PushDown(rt,m,l,r);
    double ret = 0;
    if (L <= m)
        ret += query(L, R, lson);
    if (m < R)
        ret += query(L, R, rson);
    return ret;
}
int main(){
    ios::sync_with_stdio(false), cin.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i].pos>>a[i].h>>a[i].l>>a[i].r;
    for(int i=1;i<=m;i++)
        cin>>b[i].pos>>b[i].val,v.push_back(b[i].pos);
    sort(b+1,b+m+1);
    sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    build(1,m,1);
    for(int i=1;i<=n;i++){
        int L=a[i].pos-a[i].h;
        if(v[getid(L)-1]!=L)
            L=max(1,getid(L)-1);
        else
            L=getid(L);
        int R=a[i].pos+a[i].h;
        if(v[getid(R)-1]!=R)
            R=max(1,getid(R)-1);
        else
            R=getid(R);
        int M=a[i].pos;
        if(v[getid(M)-1]!=M)
            M=max(1,getid(M)-1);
        else
            M=getid(M);
        //printf("%d %d %d\n",L,M,R);
        if(L==M&&M==R){
            upedit(L,M,a[i].r*1.0/100,1,m,1);
        }else{
            upedit(L,M,a[i].l*1.0/100,1,m,1);
            if(M<R)
            upedit(M+1,R,a[i].r*1.0/100,1,m,1);
        }
    }
    printf("%.5f\n",sum[1]);
    return 0;
}


#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<cmath>
#define lowbit(x) ((x)&(-x))
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a>b?b:a)
#define INF 0x3f3f3f3f
#define sz size()
#define pb push_back
#define ph push
#define mem(x, y) memset(x, y, sizeof(x));
#define mem0(x) mem(x,0)
#define mem1(x) mem(x,-1)
#define memINF(x) mem(x,INF)
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define rep(i,a,b) for(int i=a;i<(b);++i)
using namespace std;
typedef __int64 ll;

int const Max_N = 2e5+50;

int n,m;
int a[Max_N];
int L[Max_N];
int R[Max_N];
int l[Max_N];
int r[Max_N];
int b[Max_N];
int z[Max_N];

vector<int>v;

double p[Max_N*5] = {false};
double sum[Max_N*5] = {0};

map<int,int>mp;

double Log10[103] = {0};
void init()
{
	rep(i,1,100)
	{
		Log10[i] = log10(i/100.0);
	}
	Log10[0] = log10(0.00001);
}

int main()
{
	init();
	cin >> n >> m;
	rep(i,1,n+1)
	{
		int h;
		cin >> a[i] >> h >> l[i] >> r[i];
		R[i] = a[i] + h;
		L[i] = a[i] - h;
		v.pb(a[i]);v.pb(R[i]);v.pb(L[i]);
	}

	rep(i,1,m+1)
	{
		cin >> b[i] >> z[i];
		v.pb(b[i]);
	}

//	rep(i,0,v.sz) cout << v[i] << (i == v.sz -1?'\n':' ' );

	//---离散化
	sort(all(v));
	int k =  unique(all(v)) - v.begin();
	rep(i,0,k) mp[v[i]] = i+1;
//	rep(i,0,v.sz) cout << v[i] << (i == v.sz -1?'\n':' ' );
	rep(i,1,n+1)
	{

//		cout << a[i] << ' ' << L[i] <<' ' <<  R[i] << endl;
		a[i] = mp[a[i]];
		R[i] = mp[R[i]];
		L[i] = mp[L[i]];
//		cout << a[i] << ' ' << L[i] << ' ' <<  R[i] << endl;
	}
	rep(i,1,m+1)  b[i] = mp[b[i]];
	//----end

	///---debug----
//	rep(i,1,n+1) cout << a[i] << ' ' << L[i] << R[i] << endl;
//	rep(i,1,m+1) cout << b[i] <<endl;

	rep(i,1,n+1)
	{
		int ll = L[i];
		int rr = a[i]-1;
		double pp = Log10[100-l[i]];

	//	cout << pp << endl;
	//	cout << log10(pp) << endl;
	//	cout << pow(10.0,log10(pp)) << endl;

		p[ll] += pp,p[rr+1]-= pp;

		ll = a[i]+1;
		rr = R[i];

		pp = Log10[100-r[i]];
		p[ll] += pp,p[rr+1] -= pp;
	}

	rep(i,1,v.sz+1)
	{
		sum[i] = sum[i-1] + p[i];
	}

	double ans = 0;
	rep(i,1,m+1)
	{
		ans += z[i]*pow(10.0,sum[b[i]]);
	}
	printf("%.10f",ans);

	return 0;
}


//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<cmath>
#define lowbit(x) ((x)&(-x))
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a>b?b:a)
#define INF 0x3f3f3f3f
#define sz size()
#define pb push_back
#define ph push
#define mem(x, y) memset(x, y, sizeof(x));
#define mem0(x) mem(x,0)
#define mem1(x) mem(x,-1)
#define memINF(x) mem(x,INF)
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define rep(i,a,b) for(int i=a;i<(b);++i)
using namespace std;
typedef __int64 ll;

int const Max_N = 2e5+50;

int n,m;
int a[Max_N];
int L[Max_N];
int R[Max_N];
double l[Max_N];
double r[Max_N];
int b[Max_N];
int z[Max_N];

vector<int>v;

double p[Max_N*5] = {false};
double sum[Max_N*5] = {0};

int main()
{
	cin >> n >> m;
	rep(i,1,n+1)
	{
		int h;
		cin >> a[i] >> h >> l[i] >> r[i];
		R[i] = a[i] + h;
		L[i] = a[i] - h;
		v.pb(a[i]);v.pb(R[i]);v.pb(L[i]);
	}

	rep(i,1,m+1)
	{
		cin >> b[i] >> z[i];
		v.pb(b[i]);
	}

//	rep(i,0,v.sz) cout << v[i] << (i == v.sz -1?'\n':' ' );

	//---离散化
	sort(all(v));
	v.erase(unique(all(v)),v.end());
//	rep(i,0,v.sz) cout << v[i] << (i == v.sz -1?'\n':' ' );
	rep(i,1,n+1)
	{

//		cout << a[i] << ' ' << L[i] <<' ' <<  R[i] << endl;
		a[i] = lower_bound(all(v),a[i]) - v.begin() + 1;
		R[i] = lower_bound(all(v),R[i]) - v.begin() + 1;
		L[i] = lower_bound(all(v),L[i]) - v.begin() + 1;
//		cout << a[i] << ' ' << L[i] << ' ' <<  R[i] << endl;
	}
	rep(i,1,m+1)  b[i] = lower_bound(all(v),b[i]) - v.begin() + 1;
	//----end

	///---debug----
//	rep(i,1,n+1) cout << a[i] << ' ' << L[i] << R[i] << endl;
//	rep(i,1,m+1) cout << b[i] <<endl;

	rep(i,1,n+1)
	{
		int ll = L[i];
		int rr = a[i]-1;
		if(l[i] >= 99.999 ) l[i] = 99.999;
		double pp = (100.0-l[i])/100.0;

	//	cout << pp << endl;
	//	cout << log10(pp) << endl;
	//	cout << pow(10.0,log10(pp)) << endl;

		p[ll] += log10(pp),p[rr+1]-= log10(pp);

		ll = a[i]+1;
		rr = R[i];

		if(r[i] >= 99.999 ) r[i] = 99.999;
		pp = (100.0-r[i])/100.0;
		p[ll] += log10(pp),p[rr+1] -= log10(pp);
	}

	rep(i,1,v.sz+1)
	{
		sum[i] = sum[i-1] + p[i];
	}

	double ans = 0;
	rep(i,1,m+1)
	{
		ans += z[i]*pow(10.0,sum[b[i]]);
	}
	printf("%.10f",ans);

	return 0;
}


/**Bismillahir Rahmanir Rahim  *///{
#include <bits/stdc++.h>
using namespace std;
#define inf 1000000007
#define llinf 1000000000000000000LL
#define eps 0.000000001
#define im(_x, _mod) if (_x>=_mod) _x -= _mod; else if (_x<0) _x += _mod;
#define bug(args ...) cout << __LINE__ << ": ", err(new istringstream(string(#args)), args), cout << '\n'
inline void err(istringstream *iss) {}
template<typename T, typename ... Args> void err(istringstream *iss, const T &$val, const Args & ... args) {
    string $name; *iss >> $name; if ($name.back()==',') $name.pop_back();
    cout << $name << " = " << $val << "; ", err(iss, args ...);
}
using ll = long long; using ull = unsigned long long; using ld = long double;
int n, m, K, T, Q, cn;//}
#define mxn 100005
#define mxm 10005

int a[mxn], H[mxn], L[mxn], R[mxn];

struct mushroom
{
    int b, z;
} mus[mxm];

struct cmp { bool operator() (const mushroom &ls, const mushroom &rs) {
    return ls.b<rs.b;
}};

struct event
{
    int idx, p;
    bool strt;
} events[mxn<<2|3];
int ei;

struct cmp2 { bool operator() (const event &ls, const event &rs) {
    return tie(ls.idx, rs.strt)<tie(rs.idx, ls.strt);
}};

double p/*probability of dying*/[mxm], ans, cur;

int main() { cin.tie(NULL);

// We can use linearity of expectation (thanks to Allah I remember it). ==> For each mushroom, find it's probability of
// living from probability of dying. ==> For every tree add it's l probability to l range and r probability to r range.
// ==> As rang eis high, we can just sort and binary search the range of mushrooms. Dying prob. is P(AUB) =
// P(A)+P(B)-P(A)*P(B), where at any point u have P(A) prob. of dying already, and a new tree falling over u has P(B).
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d%d", &a[i], &H[i], &L[i], &R[i]);
    }
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &mus[i].b, &mus[i].z);
    }

    sort(mus, mus+m, cmp());
    for (int i = 0; i < n; i++) {
        int lL = int(lower_bound(mus, mus+m, mushroom{a[i]-H[i], -inf}, cmp())-mus);
        int lr = int(lower_bound(mus, mus+m, mushroom{a[i], -inf}, cmp())-mus)-1;
        int rl = int(upper_bound(mus, mus+m, mushroom{a[i], inf}, cmp())-mus);
        int rr = int(upper_bound(mus, mus+m, mushroom{a[i]+H[i], inf}, cmp())-mus)-1;
        if (L[i]) events[ei++] = {lL, L[i], 1}, events[ei++] = {lr+1, L[i], 0};
        if (R[i]) events[ei++] = {rl, R[i], 1}, events[ei++] = {rr+1, R[i], 0};
    }
    sort(events, events+(ei), cmp2());
    int cnt100 = 0;
    for (int i = 0; i < ei; i++) {
        auto &e = events[i];
        if (i and e.idx!=events[i-1].idx) {
            for (int j = events[i-1].idx; j < e.idx; j++) {
                if (cnt100) p[j] = 1; else p[j] = cur;
            }
        }
        if (e.strt) {if(e.p==100) cnt100++; else cur = cur+e.p/100.0-cur*e.p/100.0;}
        else {if(e.p==100) cnt100--; else cur = (cur-e.p/100.0)/(1-e.p/100.0);}
    }

    for (int i = 0; i < m; i++) {
        ans += mus[i].z*(1-p[i]);
    }
    printf("%.9f\n", ans);

return 0; }


/**Bismillahir Rahmanir Rahim  *///{
#include <bits/stdc++.h>
using namespace std;
#define inf 1000000007
#define llinf 1000000000000000000LL
#define eps 0.000000001
#define im(_x, _mod) if (_x>=_mod) _x -= _mod; else if (_x<0) _x += _mod;
#define bug(args ...) cout << __LINE__ << ": ", err(new istringstream(string(#args)), args), cout << '\n'
inline void err(istringstream *iss) {}
template<typename T, typename ... Args> void err(istringstream *iss, const T &$val, const Args & ... args) {
    string $name; *iss >> $name; if ($name.back()==',') $name.pop_back();
    cout << $name << " = " << $val << "; ", err(iss, args ...);
}
using ll = long long; using ull = unsigned long long; using ld = long double;
int n, m, K, T, Q, cn;//}
#define mxn 100005
#define mxm 10005

int a[mxn], H[mxn], L[mxn], R[mxn];

struct mushroom
{
    int b, z;
} mus[mxm];

struct cmp { bool operator() (const mushroom &ls, const mushroom &rs) {
    return ls.b<rs.b;
}};

struct event
{
    int idx, p;
    bool strt;
} events[mxn<<2|3];
int ei;

struct cmp2 { bool operator() (const event &ls, const event &rs) {
    return tie(ls.idx, rs.strt)<tie(rs.idx, ls.strt);
}};

double p/*probability of dying*/[mxm], ans, cur;

int main() { cin.tie(NULL);

// We can use linearity of expectation (thanks to Allah I remember it). ==> For each mushroom, find it's probability of
// living from probability of dying. ==> For every tree add it's l probability to l range and r probability to r range.
// ==> As rang eis high, we can just sort and binary search the range of mushrooms. Dying prob. is P(AUB) =
// P(A)+P(B)-P(A)*P(B), where at any point u have P(A) prob. of dying already, and a new tree falling over u has P(B).
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d%d", &a[i], &H[i], &L[i], &R[i]);
    }
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &mus[i].b, &mus[i].z);
    }

    sort(mus, mus+m, cmp());
    for (int i = 0; i < n; i++) {
        int lL = int(lower_bound(mus, mus+m, mushroom{a[i]-H[i], -inf}, cmp())-mus);
        int lr = int(lower_bound(mus, mus+m, mushroom{a[i], -inf}, cmp())-mus)-1;
        int rl = int(upper_bound(mus, mus+m, mushroom{a[i], inf}, cmp())-mus);
        int rr = int(upper_bound(mus, mus+m, mushroom{a[i]+H[i], inf}, cmp())-mus)-1;
        if (L[i]) events[ei++] = {lL, L[i], 1}, events[ei++] = {lr+1, L[i], 0};
        if (R[i]) events[ei++] = {rl, R[i], 1}, events[ei++] = {rr+1, R[i], 1};
    }
    sort(events, events+(ei), cmp2());
    int cnt100 = 0;
    for (int i = 0; i < ei; i++) {
        auto &e = events[i];
        if (i and e.idx!=events[i-1].idx) {
            for (int j = events[i-1].idx; j < e.idx; j++) {
                if (cnt100) p[j] = 1; else p[j] = cur;
            }
        }
        if (e.strt) {if(e.p==100) cnt100++; else cur = cur+e.p/100.0-cur*e.p/100.0;}
        else {if(e.p==100) cnt100--; else cur = (cur-e.p/100.0)/(1-e.p/100.0);}
    }

    for (int i = 0; i < m; i++) {
        ans += mus[i].z*(1-p[i]);
    }
    printf("%.9f\n", ans);

return 0; }


import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;

public class c551 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int m = in.nextInt();
		long[] boxes = new long[n + 1];
		int lastnonzero = 0;
		for (int i = 1; i < n + 1; i++) {
			boxes[i] = in.nextLong();
			if(boxes[i]>0){
				lastnonzero=i;
			}
		}
		long horde = m;
		int time = 0;
		ArrayDeque<Long> backguys = new ArrayDeque<Long>();
		for (int i = 0; i < lastnonzero + 1; i++) {
			//System.out.println("tick, horde of size " + horde + " at " + i);
			time++;
			if (horde >= boxes[i]) {
				//System.out.println("annihilated");
				horde -= boxes[i];
				backguys.push(boxes[i]);
				boxes[i] = 0;
			} else {
				time--;
				//System.out.println("need longer");
				//boxes[i]-=horde;
				while (horde <= boxes[i] && !backguys.isEmpty()) {
					time++;
					//System.out.println("Reinforcement of size " + backguys.peek());
					boxes[i] -= horde;
					horde += backguys.pop();
				}
				//System.out.println("AFTER REINFORCEMENT");
				//System.out.println(Arrays.toString(boxes));
				if (horde <= boxes[i]) {
					//System.out.println("No further reinforcements");
					long waves = boxes[i] / horde;
					time += waves;
					//System.out.println("Waiting "+waves);
					boxes[i] -= horde * waves;
				}
				if(boxes[i]==0){
					backguys.push(horde);
					horde = 0;
				}else{
					backguys.push(boxes[i]);
					horde-=boxes[i];
					time++;
				}

			}
			//System.out.println(time);
			//System.out.println(Arrays.toString(boxes));
			//System.out.println("HORDE:"+horde);
			//System.out.println(backguys);
		}
		System.out.println(time);
	}

}