9 10
6 2 3 1 4 8 5 9 8
3 9
6 6
9 9
9 9
9 9
2 3
3 9
3 8
6 9
5 6
 10 10
5 10 9 2 9 3 5 5 6 5
5 10
2 2
3 10
4 8
1 3
1 5
5 5
10 10
8 9
6 10
 8 10
100 100 100 100 100 100 100 100
1 8
2 8
3 8
4 8
5 8
6 8
7 8
8 8
1 1
1 5
 5 15
103 45 103 67 45
1 1
1 2
1 3
1 4
1 5
2 2
2 3
2 4
2 5
3 3
3 4
3 5
4 4
4 5
5 5
 1 1
1000000
1 1
 10 5
10 9 8 7 6 5 4 3 2 1
4 8
1 10
3 9
2 2
5 10
 9 10
5 3 10 2 4 8 7 5 1
6 9
1 8
3 3
2 7
3 5
4 6
9 9
8 8
1 9
5 6
 9 10
10 2 6 2 4 6 6 4 1
4 8
8 9
2 3
8 9
9 9
4 5
1 7
6 6
6 8
1 1
 20 8
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
4 15
1 2
2 20
7 7
13 18
7 7
3 19
3 8
 1 2
1
1 1
1 1
 8 10
5 7 3 1 4 2 1 1
5 7
3 8
2 7
4 8
4 5
2 8
4 6
1 2
4 7
3 5

54
8
8
8
8
5
54
30
46
12
 63
10
92
34
24
53
9
5
11
54
 6400
4900
3600
2500
1600
900
400
100
100
2500
 103
148
457
524
659
45
148
215
350
103
170
215
67
112
45
 1000000
 25
55
35
9
21
 21
54
10
34
16
14
1
5
55
12
 42
5
8
5
1
6
76
6
28
10
 108
3
281
1
27
1
209
27
 1
1
 7
18
20
15
5
25
7
12
10
8


import java.io.*;
import java.util.*;


/**
 *
 * @author Saju
 *
 */

public class Main {

//	static int[] dx = { 0, 1, 0, -1 };
//	static int[] dy = { -1, 0, 1, 0 };
//
//	static int[] ddx = { 0, 1, 0, -1, -1, 1, 1, -1 };
//	static int[] ddy = { -1, 0, 1, 0, -1, -1, 1, 1 };
//
//	static int[] kx = { 2, 1, -1, -2, -2, -1, 1, 2 };
//	static int[] ky = { 1, 2, 2, 1, -1, -2, -2, -1 };
//
//	static long MOD = Long.MAX_VALUE;
//
//	static final int MAX = 1000007;
//	static long INF = Long.MAX_VALUE;
//	static int INT_INF = Integer.MAX_VALUE;
//	static double PI = 3.1415926535;
//
//	private static final double EPSILON = 1e-10;
//
//	private static double dp[] = new double[MAX];

	private static Set<Integer> tree[];

	
	private static int MAXN = 300009; 
	private static int MAXA = 1000009;
	private static int BLOCK_SZ = 555;
	private static long answer = 0;
	private static long frequency[] = new long[MAXA];
	private static int arr[] = new int[MAXN];

	public static void main(String[] args) {

		InputReader in = new InputReader(System.in);

		/*
		
		
		*/

//		int test = in.nextInt();
//		for(int t = 1; t <= test; t++){
			int n = in.nextInt();
			int m = in.nextInt();
			Node[] queries = new Node[m];
			long ans[] = new long[m];
			
			for(int i = 0; i < MAXN; i++){
				arr[i] = 0;
			}
			answer = 0;
			for(int i = 0; i < MAXA; i++){
				frequency[i] = 0;
			}
			for (int i = 0; i < n; i++) {
				arr[i] = in.nextInt();
			}
			// BLOCK_SZ = (int) Math.sqrt(n);
			// if(BLOCK_SZ * BLOCK_SZ != n){
			// BLOCK_SZ++;
			// }
			
			for (int i = 0; i < m; i++) {
				int left = in.nextInt() - 1;
				int right = in.nextInt() - 1;
				queries[i] = new Node(i, left, right);
			}

			Arrays.sort(queries, new Comparator<Node>() {

				@Override
				public int compare(Node node1, Node node2) {
					if (node1.left / BLOCK_SZ != node2.left / BLOCK_SZ) {
						return (node1.left / BLOCK_SZ) - (node2.left / BLOCK_SZ);
					}
					return node1.right - node2.right;
				}
			});

			// for(int i = 0; i < m; i++){
			// System.out.println(queries[i].left + " " + queries[i].right);
			// }

			int currentLeft = 0;
			int currentRight = 0;

			for (int i = 0; i < m; i++) {
				int left = queries[i].left;
				int right = queries[i].right;
				while (currentLeft < left) {
					remove(currentLeft);
					currentLeft++;
				}
				while (currentLeft > left) {
					add(currentLeft - 1);
					currentLeft--;
				}
				while (currentRight <= right) {
					add(currentRight);
					currentRight++;
				}
				while (currentRight > right + 1) {
					remove(currentRight - 1);
					currentRight--;
				}
				// System.out.println(answer);
				ans[queries[i].index] = answer;
			}
//			System.out.println("Case " + t + ":");
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < m; i++) {
				sb.append(ans[i] + "\n");
			}
			System.out.println(sb.toString());
//		}
		
		System.exit(0);
	}

	private static void add(int position) {

		frequency[arr[position]]++;
		
		long k = frequency[arr[position]];
		int s = arr[position];
		
		if (frequency[arr[position]] == 1) {
			answer += (k * k * s);
		}
		else{
			answer += s * ((2 * k) - 1);
		}
	}

	private static void remove(int position) {
		frequency[arr[position]]--;
		
		long k = frequency[arr[position]];
		long s = arr[position];
		
		if (frequency[arr[position]] == 0) {
			answer -= ((k + 1) * (k + 1) * s);
		}
		else{
			answer += s * (-1) * ((2 * k) + 1);
		}
	}

	private static class Node {
		int index;
		int left;
		int right;

		Node(int index, int left, int right) {
			this.index = index;
			this.left = left;
			this.right = right;
		}

	}

	private static Set<Integer> query(int node, int start, int end, int left, int right) {

		if (start > right || end < left) {
			return new HashSet<>();
		}

		if (start >= left && end <= right) {
			return tree[node];
		}
		int mid = (start + end) / 2;

		query(2 * node, start, mid, left, right);
		query((2 * node) + 1, mid + 1, end, left, right);
		return null;
	}

	private static Set<Integer> combine(Set<Integer> set1, Set<Integer> set2) {
		Set<Integer> set = new HashSet<>();
		for (Integer e : set1) {
			set.add(e);
		}
		for (Integer e : set2) {
			set.add(e);
		}
		return set;
	}

	private static void buildSegTree(int node, int start, int end, int[] arr) {

		if (start == end) {
			// System.out.println("node " + node);
			tree[node].add(arr[start]);
			return;
		}
		int mid = (start + end) / 2;

		buildSegTree(2 * node, start, mid, arr);
		buildSegTree((2 * node) + 1, mid + 1, end, arr);
		// mergeSet(node, tree[2 * node], tree[(2 * node) + 1]);
		tree[node].addAll(tree[2 * node]);
		tree[node].addAll(tree[(2 * node) + 1]);
	}

	private static void mergeSet(int node, Set<Integer> set1, Set<Integer> set2) {
		Set<Integer> tempSet = new HashSet<>();
		for (Integer e : set1) {
			tempSet.add(e);
		}
		for (Integer e : set2) {
			tempSet.add(e);
		}
		tree[node] = tempSet;
	}

	// private static void update(int node, int start, int end, int idx, int
	// value, int[] arr) {
	// if(start == end){
	// arr[idx] = value;
	// tree[node] = value;
	// return;
	// }
	//
	// int mid = (start + end) / 2;
	// if(idx >= start && idx <= mid){
	// update(2 * node, start, mid, idx, value, arr);
	// }
	// else{
	// update((2 * node) + 1, mid + 1, end, idx, value, arr);
	// }
	// tree[node] = Math.min(tree[2 * node], tree[(2 * node) + 1]);
	// }
	//
	// private static int query(int node, int start, int end, int left, int
	// right) {
	// if(start > right || end < left){
	// return INT_INF;
	// }
	// if(start >= left && end <= right){
	// return tree[node];
	// }
	// int mid = (start + end) / 2;
	// int val1 = query(2 * node, start, mid, left, right);
	// int val2 = query((2 * node) + 1, mid + 1, end, left, right);
	//
	// return Math.min(val1, val2);
	// }
	//
	// private static void build(int node, int start, int end, int[] arr) {
	//
	// if(start == end){
	// tree[node] = arr[start];
	// return;
	// }
	//
	// int mid = (start + end) / 2;
	// build(2 * node, start, mid, arr);
	// build((2 * node) + 1, mid + 1, end, arr);
	// tree[node] = Math.min(tree[2 * node], tree[(2 * node) + 1]);
	//// System.out.println(node);
	// }

	private static class Pair {
		int first;
		String second;

		Pair(int first, String second) {
			this.first = first;
			this.second = second;
		}
	}

	private static class Point {
		int x;
		int y;

		Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public String toString() {

			return this.x + " " + this.y;
		}
	}

	// private static long set(long N, int pos) {
	//
	// return N = N | (1 << pos);
	// }
	// private static long check(long N, int pos) {
	//
	// return N & (1 << pos);
	// }
	// private static long reset(long N, int pos){
	//
	// return N=N|~(1<<pos);
	// }

	// nCk
	// private static long binomialCoeff(int n, int k){
	// long[] arr = new long[k + 1];
	// arr[0] = 1;
	// for(int i = 1; i <= n; i++){
	// for(int j = Math.min(i, k); j > 0; j--){
	// arr[j] = (arr[j] + arr[j - 1]) % MOD;
	// }
	// }
	// return arr[k];
	// }

	// BIT =>
	// https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/
	// static int BIT[] = new int[MAX + 5];
	//
	// private static int query(int index) {
	// int sum = 0;
	// for (; index > 0; index -= (index & (-index))) {
	// sum += BIT[index];
	// }
	// return sum;
	// }
	//
	// private static void update(int size, int index, int val) {
	// for (; index <= size; index += (index & (-index))) {
	// BIT[index] += val;
	// }
	// }

	/*
	 * 
	 * tutorial :
	 * https://helloacm.com/algorithms-series-0-1-backpack-dynamic-programming-
	 * and-backtracking/
	 * 
	 */

	// here arr and prob zero based index
	// static int backPack(int n, int m, int[] arr, double[] prob, double p) {
	// double dp[][] = new double[n + 1][m + 1];
	// for (int i = 0; i <= n; ++i) {
	// dp[i][0] = 1.0;
	// }
	// for (int i = 1; i <= n; i++) {
	// for (int j = 1; j <= m; j++) {
	//
	// if (j < arr[i - 1]) { // insufficient capacity
	// dp[i][j] = dp[i - 1][j];
	// } else {
	// dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - arr[i - 1]] * (1.0 -
	// prob[i - 1]));
	// }
	//
	// }
	// }
	// for (int i = m; i >= 0; i--) { // reverse checking the maximum weight
	// if ((1.0 - dp[n][i]) <= p) {
	// return i;
	// }
	// }
	// return 0;
	// }

	// here arr and prob one based index
	// static int backPack1(int n, int m, int[] arr, double[] prob, double p) {
	//
	// double dp[] = new double[m + 1];
	//
	// dp[0] = 1.0;
	// for (int i = 1; i <= n; i++) {
	// for (int j = m; j >= arr[i]; --j) {
	// // dp[j] = dp[j] || dp[j - A[i - 1]];
	// dp[j] = Math.max(dp[j], dp[j - arr[i]] * (1.0 - prob[i]));
	// }
	// }
	// for (int i = m; i >= 0; i--) {
	// if (1.0 - dp[i] <= p) {
	// return i;
	// }
	// }
	// return 0;
	// }

	/*
	 *
	 * tutorial :
	 * https://www.hackerearth.com/practice/algorithms/searching/ternary-search/
	 * tutorial/
	 *
	 */

	// lightoj -> 1146
	// static double ternary(Point a, Point b, Point c, Point d) {
	//
	// double l = 0;
	// double r = 1;
	//
	// for (int i = 0; i < 200; i++) {
	// double mid1 = l + ((r - l) / 3);
	// double mid2 = r - ((r - l) / 3);
	//
	// double dis1 = func(a, b, c, d, mid1);
	// double dis2 = func(a, b, c, d, mid2);
	//
	// if(dis1 > dis2){
	// l = mid1;
	//
	// }
	// else{
	// r = mid2;
	// }
	// }
	//
	// return l;
	//
	// }
	//
	// static double func(Point a, Point b, Point c, Point d, double multiple) {
	//
	// double xDifAB = b.x - a.x;
	// double yDifAB = b.y - a.y;
	// double xDifCD = d.x - c.x;
	// double yDifCD = d.y - c.y;
	//
	// double x1 = a.x + xDifAB * multiple;
	// double y1 = a.y + yDifAB * multiple;
	// double x2 = c.x + xDifCD * multiple;
	// double y2 = c.y + yDifCD * multiple;
	//
	// double distance = Math.sqrt(((x1 - x2) * (x1 - x2)) +
	// ((y1 - y2) * (y1 - y2)));
	//
	// return distance;
	// }
	//
	// static class Point{
	// double x;
	// double y;
	//
	// Point(double x, double y){
	// this.x = x;
	// this.y = y;
	// }
	// }

	// static void primeFactorization(int n) {
	// int temp = n;
	// Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	// for (int i = 2; i <= Math.sqrt(n); i++) {
	// if (n % i == 0) {
	// int count = 0;
	// while (n % i == 0) {
	// count++;
	// n = n / i;
	// }
	// System.out.println("i: " + i + ", count: " + count);
	// map.put(i, count);
	// }
	//
	// }
	// if (n != 1) {
	// System.out.println(n);
	// map.put(n, 1);
	// }
	//
	//// calculateSumOfDivisor(map, temp);
	// }

	// static int counter[] = new int[MAX];
	//
	// private static void calculateSumOfDivisor(Map<Integer, Integer> map, int
	// n) {
	// int sum = 1;
	// for(Integer key : map.keySet()){
	// int count = map.get(key);
	// sum *= ((Math.pow(key, count + 1) - 1) / (key - 1));
	// }
	// if(sum < MAX){
	// if(counter[sum] < n){
	//// System.out.println("H");
	// counter[sum] = n;
	// }
	//
	// }
	//
	//// System.out.println(sum);
	// }

	// static int phi[] = new int[MAX];
	// static int phiStepCount[] = new int[MAX];
	// static void computeTotient() {
	//
	// // Create and initialize an array to store
	// // phi or totient values
	// for (int i = 1; i < MAX; i++) {
	// phi[i] = i; // indicates not evaluated yet
	// // and initializes for product
	// // formula.
	// }
	//
	// // Compute other Phi values
	// for (int p = 2; p < MAX; p++) {
	//
	// // If phi[p] is not computed already,
	// // then number p is prime
	// if (phi[p] == p) {
	//
	// // Phi of a prime number p is
	// // always equal to p-1.
	// phi[p] = p - 1;
	//
	// // Update phi values of all
	// // multiples of p
	// for (int i = 2 * p; i < MAX; i += p) {
	//
	// // Add contribution of p to its
	// // multiple i by multiplying with
	// // (1 - 1/p)
	// phi[i] = (phi[i] / p) * (p - 1);
	// }
	//
	// // for (int i = p; i < MAX; i += p) {
	// //
	// // phi[i] -= (phi[i] / p);
	// // }
	//
	// }
	//// phiStepCount[p] = phiStepCount[phi[p]] + 1;
	// }
	//
	//// for(int i = 1; i < MAX; i++){
	//// phiStepCount[i] += phiStepCount[i - 1];
	//// }
	// }

	// public static BigInteger floorOfNthRoot(BigInteger x, int n) {
	// int sign = x.signum();
	// if (n <= 0 || (sign < 0))
	// throw new IllegalArgumentException();
	// if (sign == 0)
	// return BigInteger.ZERO;
	// if (n == 1)
	// return x;
	// BigInteger a;
	// BigInteger bigN = BigInteger.valueOf(n);
	// BigInteger bigNMinusOne = BigInteger.valueOf(n - 1);
	// BigInteger b = BigInteger.ZERO.setBit(1 + x.bitLength() / n);
	// do {
	// a = b;
	// b = a.multiply(bigNMinusOne).add(x.divide(a.pow(n - 1))).divide(bigN);
	// } while (b.compareTo(a) == -1);
	// return a;
	// }

	// O(log(max(A, B))).
	// static long gcd(long a, long b) {
	// if (b == 0)
	// return a;
	// return gcd(b, a % b);
	// }

	private static double getDistance(double x1, double y1, double x2, double y2) {

		return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
	}

	// private static int getDecimal(String str) {
	// int val = 0;
	//
	// for (int i = str.length() - 1, j = 0; i >= 0; i--, j++) {
	// if (str.charAt(i) == '1') {
	// val += Math.pow(2, j);
	// }
	// }
	// return val;
	// }

	// private static int call(int i, int j, int[][] colors) {
	//
	// if (i >= colors.length) {
	// return 0;
	// }
	//
	// if (dp[i][j] != -1) {
	// return dp[i][j];
	//
	// }
	//
	// int result = Integer.MAX_VALUE;
	//
	// for (int k = 0; k < 3; k++) {
	// if (k == j) {
	// continue;
	// } else {
	// result = Math.min(result, call(i + 1, k, colors) + colors[i][j]);
	// }
	// }
	//
	// return dp[i][j] = result;
	// }

	// static int dp[][];

	// private static BigInteger fac(int n, int mod) {
	//
	// if (n <= 0) {
	// return BigInteger.ONE;
	// }
	// return BigInteger.valueOf(n).multiply(fac(n - 1, mod));
	// }

	// private static long modInverse(long n, long m){
	// return bigMod(n, m - 2, m);
	// }

	// private static long bigMod(long n, long k, long m) {
	//
	// long ans = 1;
	// while (k > 0) {
	// if ((k & 1) == 1) {
	// ans = (ans * n) % m;
	// }
	// n = (n * n) % m;
	// k >>= 1;
	// }
	// return ans;
	// }

	// Returns an iterator pointing to the first element
	// in the range [first, last] which does not compare less than val.
	// private static int lowerBoundNew(long[] arr, long num){
	// int start = 0;
	// int end = arr.length - 1;
	// int index = 0;
	// int len = arr.length;
	// int mid = 0;
	// while(true){
	// if(start > end){
	// break;
	// }
	// mid = (start + end) / 2;
	// if(arr[mid] > num){
	// end = mid - 1;
	// }
	// else if(arr[mid] < num){
	// start = mid + 1;
	// }
	// else{
	// while(mid >= 0 && arr[mid] == num){
	// mid--;
	// }
	// return mid + 1;
	// }
	// }
	// if(arr[mid] < num){
	// return mid + 1;
	// }
	// return mid;
	// }

	// upper_bound() is a standard library function
	// in C++ defined in the header .
	// It returns an iterator pointing to
	// the first element in the range [first, last)
	// that is greater than value, or last if no such element is found
	// private static int upperBoundNew(long[] arr, long num){
	//
	// int start = 0;
	// int end = arr.length - 1;
	// int index = 0;
	// int len = arr.length;
	// int mid = 0;
	// while(true){
	// if(start > end){
	// break;
	// }
	// mid = (start + end) / 2;
	// if(arr[mid] > num){
	// end = mid - 1;
	// }
	// else if(arr[mid] < num){
	// start = mid + 1;
	// }
	// else{
	// while(mid < len && arr[mid] == num){
	// mid++;
	// }
	// if(mid == len - 1 && arr[mid] == num){
	// return mid + 1;
	// }
	// else{
	// return mid;
	// }
	// }
	// }
	// if(arr[mid] < num){
	// return mid + 1;
	// }
	// return mid;
	// }

	// private static int upperBound(long[] arr, long num) {
	//
	// int start = 0;
	// int end = arr.length;
	//
	// int mid = 0;
	// int index = 0;
	// while (true) {
	//
	//// System.out.println(start + " " + end);
	// if (start > end) {
	// break;
	// }
	// mid = (start + end) / 2;
	// if (arr[mid] > num) {
	// end = mid - 1;
	//
	// } else if (arr[mid] < num) {
	// start = mid + 1;
	// } else {
	// return mid;
	// }
	//
	//// System.out.println("a: " + start + " " + end);
	// }
	//
	// // System.out.println(mid);
	// if (arr[mid] < num) {
	// index = mid + 1;
	// } else {
	// index = mid;
	// }
	// return index;
	// }

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream));
			tokenizer = null;
		}

		public String next() {
			try {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					tokenizer = new StringTokenizer(reader.readLine());

				}
			} catch (IOException e) {
				return null;
			}
			return tokenizer.nextToken();
		}

		public String nextLine() {
			String line = null;
			try {
				tokenizer = null;
				line = reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			return line;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public boolean hasNext() {
			try {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					tokenizer = new StringTokenizer(reader.readLine());
				}
			} catch (Exception e) {
				return false;
			}
			return true;
		}
	}
}
