#include <bits/stdc++.h>
using namespace std;
struct OO {
  OO& operator<(int a) {
    printf("%d", a);
    return *this;
  }
  OO& operator<(long long a) {
    printf("%lld", a);
    return *this;
  }
  OO& operator<(double a) {
    printf("%.15f", a);
    return *this;
  }
  OO& operator<(char a) {
    putchar(a);
    return *this;
  }
  OO& operator<(const char* a) {
    fputs(a, stdout);
    return *this;
  }
} O;
struct II {
  II& operator>(int& a) {
    scanf("%d", &a);
    return *this;
  }
  II& operator>(long long& a) {
    scanf("%lld", &a);
    return *this;
  }
  II& operator>(double& a) {
    scanf("%lf", &a);
    return *this;
  }
  II& operator>(char& a) {
    a = getchar();
    return *this;
  }
} I;
struct EE {
  EE& operator<(int a) { return *this; }
  EE& operator<(long long a) { return *this; }
  EE& operator<(double a) { return *this; }
  EE& operator<(char a) { return *this; }
  EE& operator<(const char* a) { return *this; }
} E;
long double wynik = 0;
int extra[100009];
class UnionFind {
 public:
  UnionFind(size_t univSize) : parents(univSize), ranks(univSize, 0) {
    for (size_t i = 0; i < univSize; ++i) parents[i] = i;
  }
  size_t find(size_t x) {
    size_t root = x;
    while (parents[root] != root) root = parents[root];
    while (x != root) {
      size_t& curr = parents[x];
      x = parents[x];
      curr = root;
    }
    return root;
  }
  bool makeUnion(size_t a, size_t b) {
    a = find(a);
    b = find(b);
    if (a == b) return false;
    if (ranks[a] < ranks[b]) {
      parents[a] = b, ++ranks[b];
      extra[b] += extra[a];
      E < "extra[" < (int)b < "] is now " < extra[b] < '\n';
    } else {
      parents[b] = a, ++ranks[a];
      extra[a] += extra[b];
      E < "extra[" < (int)a < "] is now " < extra[a] < '\n';
    }
    return true;
  }

 private:
  std::vector<size_t> parents;
  std::vector<size_t> ranks;
};
UnionFind uf(100009);
int n, m;
int tab[100009];
struct edge {
  bool operator<(const edge& o) const { return v < o.v; }
  int fr, to, v;
} es[100009];
int main() {
  I > n > m;
  for (int i = (int)(0); i < (int)(n); ++i) {
    I > tab[i];
  }
  for (int i = (int)(0); i < (int)(n); ++i) extra[i] = 1;
  for (int i = (int)(0); i < (int)(m); ++i) {
    int a, b;
    I > a > b;
    --a;
    --b;
    es[i].fr = a;
    es[i].to = b;
    es[i].v = min(tab[a], tab[b]);
  }
  sort(es, es + m);
  for (int e = (int)(m)-1; e >= (int)(0); --e) {
    int a = es[e].fr;
    int b = es[e].to;
    a = uf.find(a);
    b = uf.find(b);
    long double mod =
        (long double)extra[a] * (long double)extra[b] * (long double)es[e].v;
    E < "a=" < a < "   b=" < b < '\n';
    E < "v " < es[e].v < "   " < extra[a] < " " < extra[b] < '\n';
    bool r = uf.makeUnion(a, b);
    if (!r) continue;
    wynik += mod;
  }
  double w = (long double)wynik / ((long double)n * (n - 1));
  O < w * 2 < '\n';
  return 0;
}
