#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T SQR(T x) {
  return x * x;
}
template <class T>
inline string TOSTR(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
template <class T>
void UPDATE_MIN(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <class T>
void UPDATE_MAX(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
int N, Q;
int A[100000];
int M[100000][20];
void RMQ_prepair() {
  int i, j;
  for (i = 0; i < N; i++) M[i][0] = i;
  for (j = 1; (1 << j) <= N; j++) {
    ;
    ;
    int window = 1 << j;
    int halfwindow = 1 << (j - 1);
    for (i = 0; i + window <= N; i++) {
      int x = M[i][j - 1];
      int y = M[i + halfwindow][j - 1];
      M[i][j] = (A[x] > A[y]) ? x : y;
    }
  }
}
int RMQ(int i, int j) {
  ;
  ;
  int diff = j - i;
  int k = 0;
  while (1 << (k + 1) <= diff) k++;
  ;
  ;
  ;
  ;
  ;
  ;
  int x = M[i][k];
  int y = M[j - (1 << k)][k];
  return (A[x] > A[y]) ? x : y;
}
struct Seg {
  int l;
  int r;
  double p;
  bool calculated;
  int mx;
  double a[5000 + 1];
  bool contains(const Seg &other) { return (l <= other.l && other.r <= r); }
};
Seg segs_obj[5000];
Seg *segs[5000];
int seg_i;
void calc_a(Seg &seg, vector<Seg *> &children) {
  double prob_p[5000 + 2];
  double prob_q[5000 + 2];
  for (int(i) = 0; (i) < (int)(Q + 2); (i)++) {
    prob_p[i] = 1.0;
    prob_q[i] = 1.0;
  }
  prob_p[0] = 0.0;
  for (__typeof((children).begin()) child1 = (children).begin();
       child1 != (children).end(); child1++) {
    Seg &child = **child1;
    int diff = seg.mx - child.mx;
    ;
    ;
    for (int(i) = diff + 1; (i) < (int)(Q + 2); (i)++) {
      prob_p[i - diff] *= child.a[i - 1];
    }
    for (int(i) = diff; (i) < (int)(Q + 1); (i)++) {
      prob_q[i - diff] *= child.a[i];
    }
  }
  double p = seg.p;
  double q = 1 - seg.p;
  for (int(i) = 0; (i) < (int)(Q + 1); (i)++) {
    seg.a[i] = prob_p[i] * p + prob_q[i] * q;
  }
  seg.calculated = true;
}
void calc(Seg &seg) {
  ;
  ;
  seg.mx = A[RMQ(seg.l, seg.r)];
  vector<Seg *> children;
  while (1) {
    if (seg_i >= Q) break;
    Seg &other = *segs[seg_i];
    if (!seg.contains(other)) break;
    seg_i++;
    children.push_back(&other);
    ;
    ;
    calc(other);
    ;
    ;
  };
  ;
  calc_a(seg, children);
  ;
  ;
}
bool compare(Seg *a, Seg *b) {
  if (a->l < b->l) return true;
  if (a->l > b->l) return false;
  if (a->r > b->r) return true;
  if (a->r < b->r) return false;
  return false;
}
int main() {
  cin >> N >> Q;
  for (int(i) = 0; (i) < (int)(N); (i)++) cin >> A[i];
  for (int(i) = 0; (i) < (int)(Q); (i)++) {
    int l, r;
    double p;
    cin >> l >> r >> p;
    l--;
    Seg s = {l, r, p, false};
    segs_obj[i] = s;
    segs[i] = &segs_obj[i];
  }
  sort(segs, segs + Q, compare);
  RMQ_prepair();
  Seg myseg = {0, N, 0.0, false};
  seg_i = 0;
  calc(myseg);
  double res = myseg.mx * myseg.a[0];
  for (int(i) = 1; (i) < (int)(Q + 1); (i)++) {
    res += (myseg.mx + i) * (myseg.a[i] - myseg.a[i - 1]);
  }
  printf("%.10f\n", res);
  return 0;
}
