#include <bits/stdc++.h>
using namespace std;
const int inf = 987654321;
const long long int INF = 123456789987654321;
FILE *fin, *fout;
int N, Q;
vector<int> arr;
struct query {
  int l, r;
  double p;
};
vector<query> qur;
vector<vector<int> > adj;
bool cmp(query a, query b) { return a.l < b.l || (a.l == b.l && a.r > b.r); }
void get_adj() {
  sort((qur).begin(), (qur).end(), cmp);
  adj.resize(Q);
  for (int i = Q; i--;) {
    for (int j = i - 1; j >= 0; j--) {
      if (qur[j].l <= qur[i].l && qur[i].r <= qur[j].r) {
        adj[j].push_back(i);
        break;
      }
    }
  }
}
struct BIT {
  vector<int> tree, lazy;
  void init() {
    tree = vector<int>(4 * N, -1);
    lazy = vector<int>(4 * N, -1);
  }
  void prop(int l, int r, int n) {
    if (l != r && lazy[n] != -1) {
      tree[2 * n] = lazy[n];
      tree[2 * n + 1] = lazy[n];
      lazy[2 * n] = lazy[n];
      lazy[2 * n + 1] = lazy[n];
    }
    lazy[n] = -1;
  }
  void udt(int a, int b, int val, int l, int r, int n) {
    if (b < l || r < a) return;
    if (a <= l && r <= b) {
      tree[n] = val;
      lazy[n] = val;
      return;
    }
    prop(l, r, n);
    int m = (l + r) >> 1;
    udt(a, b, val, l, m, 2 * n);
    udt(a, b, val, m + 1, r, 2 * n + 1);
    tree[n] = max(tree[2 * n], tree[2 * n + 1]);
  }
  int qur(int a, int b, int l, int r, int n) {
    if (b < l || r < a) return -1;
    if (a <= l && r <= b) return tree[n];
    prop(l, r, n);
    int m = (l + r) >> 1;
    return max(qur(a, b, l, m, 2 * n), qur(a, b, m + 1, r, 2 * n + 1));
  }
} bit;
vector<int> max_val, vis, root;
void dfs(int now) {
  vis[now] = 1;
  for (int i = 0; i < adj[now].size(); i++) {
    dfs(adj[now][i]);
  }
  max_val[now] = bit.qur(qur[now].l, qur[now].r, 0, N - 1, 1);
  bit.udt(qur[now].l, qur[now].r, -1, 0, N - 1, 1);
}
void get_max_val() {
  bit.init();
  for (int i = 0; i < N; i++) {
    bit.udt(i, i, arr[i], 0, N - 1, 1);
  }
  max_val.resize(Q);
  vis = vector<int>(Q, 0);
  for (int i = 0; i < Q; i++) {
    if (!vis[i]) {
      dfs(i);
      root.push_back(i);
    }
  }
}
int maxi;
vector<vector<double> > cache;
double dp(int now, int upper) {
  double& ret = cache[now][upper];
  if (ret != -1.0) return ret;
  if (max_val[now] > maxi + upper - Q) return ret = 0.0;
  double tmp1 = 1.0;
  for (int i = 0; i < adj[now].size(); i++) {
    tmp1 *= dp(adj[now][i], upper);
  }
  double tmp2 = 0.0;
  if (max_val[now] + 1 <= maxi + upper - Q) {
    tmp2 = 1.0;
    for (int i = 0; i < adj[now].size(); i++) {
      tmp2 *= dp(adj[now][i], upper - 1);
    }
  }
  return ret = qur[now].p * tmp2 + (1 - qur[now].p) * tmp1;
}
vector<double> prob;
void solve() {
  maxi = -1;
  for (int i = 0; i < N; i++) {
    maxi = max(maxi, arr[i]);
  }
  cache = vector<vector<double> >(Q, vector<double>(2 * Q + 1, -1.0));
  prob.resize(Q + 1);
  for (int i = 0; i <= Q; i++) {
    vis = vector<int>(Q, 0);
    prob[i] = 1.0;
    for (int j = 0; j < root.size(); j++) {
      prob[i] *= dp(root[j], i + Q);
    }
  }
  double ans = prob[0] * (double)maxi;
  for (int i = 1; i <= Q; i++) {
    ans += (prob[i] - prob[i - 1]) * (double)(maxi + i);
  }
  printf("%.20lf", ans);
}
int main() {
  scanf("%d %d", &N, &Q);
  arr.resize(N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &arr[i]);
  }
  qur.resize(Q);
  for (int i = 0; i < Q; i++) {
    int l, r;
    double p;
    scanf("%d %d %lf", &l, &r, &p);
    qur[i] = {--l, --r, p};
  }
  get_adj();
  get_max_val();
  solve();
}
