#include <bits/stdc++.h>   namespace ZDY {   #pragma GCC optimize(3)   template <class T>   __inline__ __attribute__((always_inline)) T ABS(T x) {     return x > 0 ? x : -x;   }   template <class T>   __inline__ __attribute__((always_inline)) T MAX(T x, T y) {     return x > y ? x : y;   }   template <class T>   __inline__ __attribute__((always_inline)) T MIN(T x, T y) {     return x < y ? x : y;   }   template <class T>   __inline__ __attribute__((always_inline)) T GCD(T x, T y) {     return y ? GCD(y, x % y) : x;   }   template <class T>   __inline__ __attribute__((always_inline)) void SWAP(T& x, T& y) {     T t = x;     x = y;     y = t;   }   }  // namespace ZDY   using namespace ZDY;   using namespace std;   namespace IO {   const char* ln =   n ;   const int str = 1 << 20;   struct IN {     char buf[str], *s, *t;     bool _;     IN() : s(buf), t(buf), _(0) {}     __inline__ __attribute__((always_inline)) char gc() {       return s == t && ((t = (s = buf) + fread(buf, 1, str, stdin)) == s)                  ? EOF                  : (*s++);     }     IN& operator>>(char& ch) {       if (_) return *this;       char c;       while ((c = gc()) != EOF && isspace(c))         ;       if (c == EOF)         _ = 1;       else         ch = c;       return *this;     }     IN& operator>>(char* ch) {       memset(ch, 0, sizeof(ch));       if (_) return *this;       char c;       while ((c = gc()) != EOF && isspace(c))         ;       if (c == EOF) return _ = 1, *this;       *ch = c;       ch++;       while ((c = gc()) != EOF && !isspace(c)) *ch = c, ch++;       if (c == EOF) _ = 1;       return *this;     }     IN& operator>>(string& ch) {       if (_) return *this;       char c;       while ((c = gc()) != EOF && isspace(c))         ;       if (c == EOF) return _ = 1, *this;       ch += c;       while ((c = gc()) != EOF && !isspace(c)) ch += c;       if (c == EOF) _ = 1;       return *this;     }     template <typename T>     IN& operator>>(T& x) {       if (_) return *this;       char c = gc();       bool ff = 0;       while (c != EOF && (c <  0  || c >  9 )) ff ^= (c ==  - ), c = gc();       if (c == EOF) {         _ = 1;         return *this;       }       x = 0;       while (c != EOF &&  0  <= c && c <=  9 )         x = (x << 3) + (x << 1) + c - 48, c = gc();       if (c == EOF) _ = 1;       if (ff) x = -x;       return *this;     }   } in;   struct OUT {     char buf[str], *s, *t;     OUT() : s(buf), t(buf + str) {}     ~OUT() { fwrite(buf, 1, s - buf, stdout); }     void pt(char c) {       (s == t) ? (fwrite(s = buf, 1, str, stdout), *s++ = c) : (*s++ = c);     }     OUT& operator<<(const char* s) {       while (*s) pt(*s++);       return *this;     }     OUT& operator<<(char* s) {       while (*s) pt(*s++);       return *this;     }     OUT& operator<<(string s) {       for (int i = 0; s[i]; i++) pt(s[i]);       return *this;     }     template <typename T>     OUT& operator<<(T x) {       if (!x) return pt( 0 ), *this;       if (x < 0) pt( - ), x = -x;       char a[30], t = 0;       while (x) a[t++] = x % 10, x /= 10;       while (t--) pt(a[t] +  0 );       return *this;     }   } out;   }  // namespace IO   using namespace IO;   int n, b[1000011], a[1000011], cnt = 0, head[1000011];   bool cmp(int x, int y) { return a[x] > a[y]; }   bool cmp2(int x, int y) { return a[x] < a[y]; }   struct edge {     int to, nxt;   } e[1000011 * 2];   void add(int x, int y) {     e[++cnt].to = y;     e[cnt].nxt = head[x];     head[x] = cnt;   }   int f[1000011], sz[1000011];   int gf(int x) { return (x == f[x]) ? x : (f[x] = gf(f[x])); }   bool v[1000011];   int main() {     in >> n;     for (int i = 1; i <= n; ++i) in >> a[i], b[i] = i;     sort(b + 1, b + n + 1, cmp2);     int x, y;     for (int i = 1; i <= n - 1; ++i) in >> x >> y, add(x, y), add(y, x);     long long ans = 0;     for (int i = 1; i <= n; ++i) f[i] = i, sz[i] = 1;     for (int i = 1; i <= n; ++i) {       x = b[i];       v[x] = 1;       int t = 0;       for (int i = head[x], to; to = e[i].to, i; i = e[i].nxt)         if (v[to]) {           ans += 1ll * sz[x] * sz[gf(to)] * a[x];           sz[x] += sz[gf(to)];           f[gf(to)] = x;         }     }     memset(v, 0, sizeof(v));     for (int i = 1; i <= n; ++i) f[i] = i, sz[i] = 1;     sort(b + 1, b + n + 1, cmp);     for (int i = 1; i <= n; ++i) {       x = b[i];       v[x] = 1;       int t = 0;       for (int i = head[x], to; to = e[i].to, i; i = e[i].nxt)         if (v[to]) {           ans -= 1ll * sz[x] * sz[gf(to)] * a[x];           sz[x] += sz[gf(to)];           f[gf(to)] = x;         }     }     out << ans << ln;   }