As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are given an integer d and a tree consisting of n nodes. Each node i has a value ai associated with it.

We call a set S of tree nodes valid if following conditions are satisfied:

  1. S is non-empty.
  2. S is connected. In other words, if nodes u and v are in S, then all nodes lying on the simple path between u and v should also be presented in S.
  3. <image>.



Your task is to count the number of valid sets. Since the result can be very large, you must print its remainder modulo 1000000007 (109 + 7).

Input

The first line contains two space-separated integers d (0 ≤ d ≤ 2000) and n (1 ≤ n ≤ 2000).

The second line contains n space-separated positive integers a1, a2, ..., an(1 ≤ ai ≤ 2000).

Then the next n - 1 line each contain pair of integers u and v (1 ≤ u, v ≤ n) denoting that there is an edge between u and v. It is guaranteed that these edges form a tree.

Output

Print the number of valid sets modulo 1000000007.

Examples

Input

1 4
2 1 3 2
1 2
1 3
3 4


Output

8


Input

0 3
1 2 3
1 2
2 3


Output

3


Input

4 8
7 8 7 5 4 6 4 10
1 6
1 2
5 8
1 3
3 5
6 7
3 4


Output

41

Note

In the first sample, there are exactly 8 valid sets: {1}, {2}, {3}, {4}, {1, 2}, {1, 3}, {3, 4} and {1, 3, 4}. Set {1, 2, 3, 4} is not valid, because the third condition isn't satisfied. Set {1, 4} satisfies the third condition, but conflicts with the second condition.
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.Locale;
import java.util.Comparator;
import java.io.OutputStream;
import java.util.RandomAccess;
import java.io.PrintWriter;
import java.util.AbstractList;
import java.io.Writer;
import java.util.List;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Jacob Jiang
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskD {
    private static final long MOD = (long) (1e9 + 7);
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int d = in.nextInt();
        int n = in.nextInt();
        int[] a = in.nextIntArray(n);
        int[] from = new int[n - 1];
        int[] to = new int[n - 1];
        ArrayUtils.readIntArrays(in, from, to);
        ArrayUtils.decreaseByOne(from, to);
        int[] index = new int[n];
        for (int i = 0; i < n; i++) {
            index[i] = i;
        }
        Collections.sort(ArrayUtils.asList(index), (o1, o2) -> Integer.compare(a[o1], a[o2]));
        boolean[] mark = new boolean[n];
        Graph graph = new BidirectionalFixedGraph(n, from, to);
        long answer = 0;
        for (int i : index) {
            long p = search(graph, mark, a, n, i, a[i] + d) - 1;
//            System.out.println("i + 1 = " + (i + 1));
//            System.out.println("p = " + p);
            mark[i] = true;
            answer += p;
            if (answer >= MOD)
                answer -= MOD;
        }
        out.println(answer);
    }

    private long search(Graph graph, boolean[] mark, int[] a, int n, int i, int upperBound) {
        boolean[] visited = new boolean[n];
        return dfs(graph, mark, a, i, upperBound, visited) % MOD;
    }

    private long dfs(Graph graph, boolean[] mark, int[] a, int cur, int upperBound, boolean[] visited) {
        visited[cur] = true;
        long result = 1;
        for (int next : graph.getConnectedNodes(cur)) {
            if (!mark[next] && !visited[next] && a[next] <= upperBound) {
                result *= dfs(graph, mark, a, next, upperBound, visited);
                result %= MOD;
            }
        }
        return result + 1;
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1 << 16];
    private int curChar;
    private int numChars;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int nextInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c & 15;
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public static boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public int[] nextIntArray(int count) {
        int[] result = new int[count];
        for (int i = 0; i < count; i++) {
            result[i] = nextInt();
        }
        return result;
    }

}

class OutputWriter {
    private PrintWriter writer;

    public OutputWriter(OutputStream stream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream)));
    }

    public void println(long x) {
        writer.println(x);
    }

    public void close() {
        writer.close();
    }

}

class ArrayUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++) {
                arrays[j][i] = in.nextInt();
            }
        }
    }


    public static void decreaseByOne(int[]... arrays) {
        for (int[] array : arrays) {
            for (int i = 0; i < array.length; i++) {
                array[i]--;
            }
        }
    }


    public static List<Integer> asList(int[] array) {
        return new IntList(array);
    }


    private static class IntList extends AbstractList<Integer> implements RandomAccess {

        int[] array;

        private IntList(int[] array) {
            this.array = array;
        }

        public Integer get(int index) {
            return array[index];
        }

        public Integer set(int index, Integer element) {
            int result = array[index];
            array[index] = element;
            return result;
        }

        public int size() {
            return array.length;
        }
    }


}

interface Graph {
    public int[] getConnectedNodes(int vertexNo);
}

class BidirectionalFixedGraph extends FixedGraph {
    public BidirectionalFixedGraph(int vertexCount, int[] from, int[] to) {
        if (from.length != to.length) {
            throw new IllegalArgumentException();
        }
        edges = new int[vertexCount][];
        int[] degree = new int[vertexCount];
        for (int i = 0; i < from.length; i++) {
            degree[from[i]]++;
            degree[to[i]]++;
        }
        for (int i = 0; i < vertexCount; i++) {
            edges[i] = new int[degree[i]];
        }
        for (int i = 0; i < from.length; i++) {
            edges[from[i]][--degree[from[i]]] = to[i];
            edges[to[i]][--degree[to[i]]] = from[i];
        }
    }
}

abstract class FixedGraph implements Graph {
    protected int[][] edges;

    public int[] getConnectedNodes(int vertexNo) {
        return edges[vertexNo];
    }

}

