The spring is coming and it means that a lot of fruits appear on the counters. One sunny day little boy Valera decided to go shopping. He made a list of m fruits he wanted to buy. If Valera want to buy more than one fruit of some kind, he includes it into the list several times. 

When he came to the fruit stall of Ashot, he saw that the seller hadn't distributed price tags to the goods, but put all price tags on the counter. Later Ashot will attach every price tag to some kind of fruits, and Valera will be able to count the total price of all fruits from his list. But Valera wants to know now what can be the smallest total price (in case of the most «lucky» for him distribution of price tags) and the largest total price (in case of the most «unlucky» for him distribution of price tags).

Input

The first line of the input contains two integer number n and m (1 ≤ n, m ≤ 100) — the number of price tags (which is equal to the number of different kinds of fruits that Ashot sells) and the number of items in Valera's list. The second line contains n space-separated positive integer numbers. Each of them doesn't exceed 100 and stands for the price of one fruit of some kind. The following m lines contain names of the fruits from the list. Each name is a non-empty string of small Latin letters which length doesn't exceed 32. It is guaranteed that the number of distinct fruits from the list is less of equal to n. Also it is known that the seller has in stock all fruits that Valera wants to buy.

Output

Print two numbers a and b (a ≤ b) — the minimum and the maximum possible sum which Valera may need to buy all fruits from his list.

Examples

Input

5 3
4 2 1 10 5
apple
orange
mango


Output

7 19


Input

6 5
3 5 1 6 8 1
peach
grapefruit
banana
orange
orange


Output

11 30

import java.io.*;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Main {

    static final int INF = Integer.MAX_VALUE;

    static void mergeSort(int[] a, int p, int r) {
        if (p < r) {
            int q = (p + r) / 2;
            mergeSort(a, p, q);
            mergeSort(a, q + 1, r);
            merge(a, p, q, r);
        }
    }

    static void merge(int[] a, int p, int q, int r) {
        int n1 = q - p + 1;
        int n2 = r - q;
        int[] L = new int[n1 + 1], R = new int[n2 + 1];
        // int[] L1 = new int[n1 + 1], R1 = new int[n2 + 1];

        for (int i = 0; i < n1; i++) {
            L[i] = a[p + i];
            //  L1[i] = b[p + i];

        }
        for (int i = 0; i < n2; i++) {
            R[i] = a[q + 1 + i];
            // R1[i] = b[q + 1 + i];

        }
        L[n1] = R[n2] = INF;
        // L1[n1] = R1[n2] = INF;

        for (int k = p, i = 0, j = 0; k <= r; k++) {
            if (L[i] <= R[j]) {

                a[k] = L[i++];
                //  b[k] = L1[i++];

            } else {
                a[k] = R[j++];
                // b[k] = R1[j++];

            }
        }
    }

    static void mergeSort(int[] a, int[] b, int p, int r) {
        if (p < r) {
            int q = (p + r) / 2;
            mergeSort(a, b, p, q);
            mergeSort(a, b, q + 1, r);
            merge(a, b, p, q, r);
        }
    }

    static void merge(int[] a, int[] b, int p, int q, int r) {
        int n1 = q - p + 1;
        int n2 = r - q;
        int[] L = new int[n1 + 1], R = new int[n2 + 1];
        int[] L1 = new int[n1 + 1], R1 = new int[n2 + 1];
        // int[] L2 = new int[n1 + 1], R2 = new int[n2 + 1];
        // int[] L2 = new int[n1 + 1], R2 = new int[n2 + 1];

        for (int i = 0; i < n1; i++) {
            L[i] = a[p + i];
            L1[i] = b[p + i];
            //   L2[i] = c[p + i];
            // L2[i] = a[p + i];
        }
        for (int i = 0; i < n2; i++) {
            R[i] = a[q + 1 + i];
            R1[i] = b[q + 1 + i];
            // R2[i] = c[q + 1 + i];
            //  R2[i] = a[q + 1 + i];
        }
        L[n1] = R[n2] = INF;
        L1[n1] = R1[n2] = INF;
        //  L2[n1] = R2[n2] = INF;
        int j = 0, k = 0;
        for (int i = p; i <= r; i++) {
            if (L[j] < R[k]) {
                a[i] = L[j];
                b[i] = L1[j++];
                //j++;
            } else if ((L[j] > R[k])) {
                a[i] = R[k];
                b[i] = R1[k++];
                //k++;
            } else {
                //des
                if (L1[j] > R1[k]) {
                    a[i] = L[j];
                    b[i] = L1[j++];
                    //j++;
                } else {
                    a[i] = R[k];
                    b[i] = R1[k++];
                }
            }

        }
    }

    public static int[] sieve(int n) {
        int a[] = new int[n + 1];
        for (int i = 2; i <= n; i++) {
            a[i] = 1;
        }
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (a[i] == 1) {
                for (int k = 2; i * k <= n; k++) {
                    a[i * k] = 0;
                }
            }
        }
        return a;
    }

    public static long sum(int a) {
        long su = 0;
        while (a > 0) {
            su += (long) a % 10;
            a /= 10;
        }
        return su;
    }

    public static boolean prime(int n) {
        if (n == 1) {
            return true;
        }

        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

    public static boolean isvowel(char c) {
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y') {
            return true;
        } else {
            return false;
        }
    }

    static long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static List<Integer> gd(int a, int b) {
        int m = (int) gcd(a, b);
        List<Integer> q = new ArrayList();
        for (int i = 1; i * i <= m; ++i) {
            if (m % i == 0) {
                q.add(i);
                if (i != m / i) {
                    q.add(m / i);
                }
            }
        }
        return q;
    }

    static long sum(long n) {
        return n * (n + 1) / 2;
    }

    static int divisors(int n, int m) {
        if (n - (m + (m * m)) >= 0) {
            return m;
        }
        for (int i = (int) Math.sqrt(m); i >= 1; i--) {
            if (m % i == 0 && n - (m + (m * i)) >= 0) {
                return i;
            }
        }
        return 1;
    }

    static boolean cal(int val, int k, int t) {
        int res = val, p = 1;
        while (val / Math.pow(k, p) > 0) {
            res += val / Math.pow(k, p);
            p++;
        }
        return res >= t;
    }

    static int Last_Ocuu(int[] a, int n, long v) {
        int start = 0, end = n - 1, mid, ans = -1;

        while (start <= end) {
            mid = (start + end) >> 1;
            if (a[mid] < v) {
                ans = mid;
                end = mid - 1;
            } else if (a[mid] >= v) {
                //ans=mid;
                start = mid + 1;
            }

        }
        return ans;
    }

    static long Last_Ocuu(long a, long b, long n) {
        long f = -1000, end = 1000;
        while (f <= end) {
            long mid = (f + end) >> 1;
            if (a * (Math.pow(mid, n)) == b) {
                return mid;
            } else if (a * (Math.pow(mid, n)) > b) {
                end = mid - 1;
            } else {
                f = mid + 1;
            }
        }
        return -1;
    }

    static void print(int a, String s) {

        if (a > 0) {
            //s+='*';
            System.out.println(s);
            print(a - 1, '*' + s);
        } else {
            return;
        }
    }

    static long summtion(int[] a) {
        long s = 0;
        for (int i = 0; i < a.length; i++) {
            s += (long) a[i];
        }
        return s;
    }

    static boolean vv(int i, int j, int n, int m) {
        if (i >= 0 && i < n && j < m && j >= 0) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws IOException, ParseException {
        Scannerr in = new Scannerr(System.in);
        PrintWriter or = new PrintWriter(System.out);
        //   BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
        int n = in.nextInt(),m=in.nextInt();
        Map<String,Integer> map = new TreeMap();
        
        int [] a= new int[n];
        for (int i = 0; i < n; i++) 
            a[i]=in.nextInt();
        for (int i = 0; i < m; i++) {
            String h=in.nextLine();
            if (map.containsKey(h)) {
                map.put(h, map.get(h)+1);
            }
            else map.put(h, 1);
        }
            Object[]s1=  map.values().toArray();
            int [] s= new int[s1.length];
            for (int i = 0; i < s1.length; i++) {
            s[i]=(Integer)s1[i];
        }
        Arrays.sort(s);
        mergeSort(a, 0, n-1);
        long max =0;
        int r=m;
        for (int i = n-1,le=s.length-1; i>=0&&le>=0; i--,le--) {
            if (m==0)    break;
            max+=(long)(s[le]*a[i]);
            m-=s[le];
        }
        long min=0;
        for (int i = 0,le=s.length-1; i < n; i++,le--) {
            if(r==0)break;
            min+=(long)(s[le]*a[i]);
            r-=s[le];
        }
        or.println(min+" "+max);
        or.flush();

}

static class Scannerr {

    StringTokenizer st;
    BufferedReader br;

    public Scannerr(FileReader fileReader) throws FileNotFoundException {
        br = new BufferedReader(fileReader);
    }

    public Scannerr(InputStream s) throws FileNotFoundException {
        br = new BufferedReader(new InputStreamReader(s));
    }

    public String next() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(br.readLine());
        }
        return st.nextToken();
    }

    public double nextDouble() throws IOException {
        String x = next();
        StringBuilder sb = new StringBuilder("0");
        double res = 0, f = 1;
        boolean dec = false, neg = false;
        int start = 0;
        if (x.charAt(0) == '-') {
            neg = true;
            start++;
        }
        for (int i = start; i < x.length(); i++) {
            if (x.charAt(i) == '.') {
                res = Long.parseLong(sb.toString());
                sb = new StringBuilder("0");
                dec = true;
            } else {
                sb.append(x.charAt(i));
                if (dec) {
                    f *= 10;
                }
            }
        }
        res += Long.parseLong(sb.toString()) / f;
        return res * (neg ? -1 : 1);
    }

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

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

    public String nextLine() throws IOException {
        return br.readLine();
    }

    public boolean ready() throws IOException {
        return br.ready();
    }

}



}

class Pair {

    int ind;
    int val;

    //int min;
    public Pair(int n, int p) {
        ind = n;
        val = p;
        // min = m;
    }

}
