import java.io.*;
import java.lang.management.MemoryUsage;
import java.util.*;

/**
 * @author Pavel Mavrin
 */
public class D {

    private static final int BUBEN = 1500;
    private static final int SIZE = 15000000;

    public D() throws FileNotFoundException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
//        br = new BufferedReader(new FileReader("input.txt"));
//        out = new PrintWriter("output.txt");
    }

    private void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        List<Edge>[] byCol = new List[m];
        for (int i = 0; i < m; i++) {
            int x = nextInt() - 1;
            int y = nextInt() - 1;
            int c = nextInt() - 1;
            if (byCol[c] == null) {
                byCol[c] = new ArrayList<Edge>();
            }
            byCol[c].add(new Edge(x, y));
        }
        Arrays.sort(byCol, new Comparator<List<Edge>>() {
            public int compare(List<Edge> o1, List<Edge> o2) {
                int a = o1 == null ? 0 : o1.size();
                int b = o2 == null ? 0 : o2.size();
                return Integer.compare(a, b);
            }
        });
        init(n, BUBEN);
        int[] r = new int[2 * BUBEN];
        int rn;
        Map<Pair, Integer> small = new HashMap<Pair, Integer>();
        List<int[]> big = new ArrayList<int[]>();
        int cc = 0;
        for (List<Edge> edges : byCol) {
            if (edges == null) continue;
            if (edges.size() < BUBEN) {
                rn = 0;
                for (Edge edge : edges) {
                    r[rn++] = edge.x;
                    r[rn++] = edge.y;
                }
                reinit(r, rn);
                for (Edge edge : edges) {
                    addEdge(edge.x, edge.y);
                }
                for (int i = 0; i < rn; i++) {
                    int x = r[i];
                    if (!z[x]) {
                        pn = 0;
                        dfs(x);
                        for (int ii = 0; ii < pn; ii++) {
                            for (int jj = ii + 1; jj < pn; jj++) {
//                                Pair pair = new Pair(p[ii], p[jj]);
                                cc++;
                                add(p[ii], p[jj]);
//                                Integer q = small.get(pair);
//                                if (q == null) {
//                                    small.put(pair, 1);
//                                } else {
//                                    small.put(pair, q + 1);
//                                }
                            }
                        }
                    }
                }
            } else {
                int[] p = new int[n];
                for (int i = 0; i < n; i++) {
                    p[i] = i;
                }
                for (Edge edge : edges) {
                    join(p, edge.x, edge.y);
                }
                big.add(p);
            }
        }
        int q = nextInt();
        for (int i = 0; i < q; i++) {
            int u = nextInt() - 1;
            int v = nextInt() - 1;
            int res = get(u, v);
            for (int[] p : big) {
                if (get(p, u) == get(p, v)) {
                    res++;
                }
            }
            out.println(res);
        }
//        System.out.println(cc);
//        System.out.println(big.size() + " " + small.size());
//        System.out.println(MemoryUsage.);
    }

    Random random = new Random();

    private void join(int[] p, int x, int y) {
        x = get(p, x);
        y = get(p, y);
        if (random.nextBoolean()) p[x] = y;
        else p[y] = x;
    }

    private int get(int[] p, int x) {
        if (p[x] == x) return x;
        p[x] = get(p, p[x]);
        return p[x];
    }

    int[] ww = new int[SIZE];
    int[] zz = new int[SIZE];

    void add(int u, int v) {
        if (u > v) {
            int t = u; u = v; v = t;
        }
        int h = hash(u, v);
        int h2 = hash2(u, v);
        while (ww[h] != 0) {
            if (ww[h] == h2) {
                zz[h]++;
                return;
            }
            h++;
            if (h == SIZE) h = 0;
        }
        ww[h] = h2;
        zz[h] = 1;
    }

    int get(int u, int v) {
        if (u > v) {
            int t = u; u = v; v = t;
        }
        int h = hash(u, v);
        int h2 = hash2(u, v);
        while (ww[h] != 0) {
            if (ww[h] == h2) {
                return zz[h];
            }
            h++;
            if (h == SIZE) h = 0;
        }
        return 0;
    }

    private int hash(int u, int v) {
        return ((u * 239 + v) * 239) % SIZE;
    }

    private int hash2(int u, int v) {
        return ((u * 239239 + v) * 239239);
    }

    class Pair {
        int x, y;

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

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Pair pair = (Pair) o;

            if (x != pair.x) return false;
            if (y != pair.y) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            return result;
        }
    }

    class Edge {
        int x, y;

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

    void init(int n, int m) {
        m *= 2;
        this.n = n;
        this.m = m;
        last = 0;
        head = new int[n];
        nx = new int[m];
        dst = new int[m];
        Arrays.fill(head, -1);
        z = new boolean[n];
        p = new int[n];
    }

    void reinit(int[] r, int rn) {
        for (int i = 0; i < rn; i++) {
            head[r[i]] = -1;
            z[r[i]] = false;
        }
        last = 0;
    }

    void addEdge(int x, int y) {
        nx[last] = head[x];
        dst[last] = y;
        head[x] = last;
        last++;
        nx[last] = head[y];
        dst[last] = x;
        head[y] = last;
        last++;
    }

    private void dfs(int x) {
        if (z[x]) return;
        p[pn++] = x;
        z[x] = true;
        int j = head[x];
        while (j >= 0) {
            int y = dst[j];
            dfs(y);
            j = nx[j];
        }
    }

    int n, m;
    int[] head;
    int[] nx;
    int[] dst;
    boolean[] z;
    int last;
    int[] p;
    int pn;

    BufferedReader br;
    PrintWriter out;

    StringTokenizer st;

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

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

    public static void main(String[] args) throws IOException {
        new D().run();
    }

    private void run() throws IOException {
        solve();
        out.close();
    }

}


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

/**
 * @author Pavel Mavrin
 */
public class D {

    private static final int BUBEN = 500;
    private static final int SIZE = 10000000;
    private int mapSize;

    public D() throws FileNotFoundException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
//        br = new BufferedReader(new FileReader("input.txt"));
//        out = new PrintWriter("output.txt");
    }

    private void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        List<Edge>[] byCol = new List[m];
        for (int i = 0; i < m; i++) {
            int x = nextInt() - 1;
            int y = nextInt() - 1;
            int c = nextInt() - 1;
            if (byCol[c] == null) {
                byCol[c] = new ArrayList<Edge>();
            }
            byCol[c].add(new Edge(x, y));
        }
        Arrays.sort(byCol, new Comparator<List<Edge>>() {
            public int compare(List<Edge> o1, List<Edge> o2) {
                int a = o1 == null ? 0 : o1.size();
                int b = o2 == null ? 0 : o2.size();
                return Integer.compare(a, b);
            }
        });
        init(n, BUBEN);
        int[] r = new int[2 * BUBEN];
        int rn;
        Map<Pair, Integer> small = new HashMap<Pair, Integer>();
        List<int[]> big = new ArrayList<int[]>();
        int cc = 0;
        for (List<Edge> edges : byCol) {
            if (edges == null) continue;
            if (edges.size() < BUBEN) {
                rn = 0;
                for (Edge edge : edges) {
                    r[rn++] = edge.x;
                    r[rn++] = edge.y;
                }
                reinit(r, rn);
                for (Edge edge : edges) {
                    addEdge(edge.x, edge.y);
                }
                for (int i = 0; i < rn; i++) {
                    int x = r[i];
                    if (!z[x]) {
                        pn = 0;
                        dfs(x);
                        for (int ii = 0; ii < pn; ii++) {
                            for (int jj = ii + 1; jj < pn; jj++) {
//                                Pair pair = new Pair(p[ii], p[jj]);
                                cc++;
                                add(p[ii], p[jj]);
//                                Integer q = small.get(pair);
//                                if (q == null) {
//                                    small.put(pair, 1);
//                                } else {
//                                    small.put(pair, q + 1);
//                                }
                            }
                        }
                    }
                }
            } else {
                int[] p = new int[n];
                for (int i = 0; i < n; i++) {
                    p[i] = i;
                }
                for (Edge edge : edges) {
                    join(p, edge.x, edge.y);
                }
                big.add(p);
            }
        }
        int q = nextInt();
        for (int i = 0; i < q; i++) {
            int u = nextInt() - 1;
            int v = nextInt() - 1;
            int res = get(u, v);
            for (int[] p : big) {
                if (get(p, u) == get(p, v)) {
                    res++;
                }
            }
            out.println(res);
        }
//        System.out.println(cc);
//        System.out.println(big.size() + " " + small.size());
//        System.out.println(MemoryUsage.);
    }

    Random random = new Random();

    private void join(int[] p, int x, int y) {
        x = get(p, x);
        y = get(p, y);
        if (random.nextBoolean()) p[x] = y;
        else p[y] = x;
    }

    private int get(int[] p, int x) {
        if (p[x] == x) return x;
        p[x] = get(p, p[x]);
        return p[x];
    }

    int[] ww = new int[SIZE];
    int[] zz = new int[SIZE];

    void add(int u, int v) {
        if (u > v) {
            int t = u; u = v; v = t;
        }
        int h = hash(u, v);
        int h2 = hash2(u, v);
        while (ww[h] != 0) {
            if (ww[h] == h2) {
                zz[h]++;
                return;
            }
            h++;
            if (h == SIZE) h = 0;
        }
        ww[h] = h2;
        mapSize++;
        if (mapSize > SIZE * 0.8) throw new RuntimeException();

        zz[h] = 1;
    }

    int get(int u, int v) {
        if (u > v) {
            int t = u; u = v; v = t;
        }
        int h = hash(u, v);
        int h2 = hash2(u, v);
        while (ww[h] != 0) {
            if (ww[h] == h2) {
                return zz[h];
            }
            h++;
            if (h == SIZE) h = 0;
        }
        return 0;
    }

    private int hash(int u, int v) {
        return ((u * 239 + v) * 239) % SIZE;
    }

    private int hash2(int u, int v) {
        return ((u * 239239 + v) * 239239);
    }

    class Pair {
        int x, y;

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

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Pair pair = (Pair) o;

            if (x != pair.x) return false;
            if (y != pair.y) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            return result;
        }
    }

    class Edge {
        int x, y;

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

    void init(int n, int m) {
        m *= 2;
        this.n = n;
        this.m = m;
        last = 0;
        head = new int[n];
        nx = new int[m];
        dst = new int[m];
        Arrays.fill(head, -1);
        z = new boolean[n];
        p = new int[n];
    }

    void reinit(int[] r, int rn) {
        for (int i = 0; i < rn; i++) {
            head[r[i]] = -1;
            z[r[i]] = false;
        }
        last = 0;
    }

    void addEdge(int x, int y) {
        nx[last] = head[x];
        dst[last] = y;
        head[x] = last;
        last++;
        nx[last] = head[y];
        dst[last] = x;
        head[y] = last;
        last++;
    }

    private void dfs(int x) {
        if (z[x]) return;
        p[pn++] = x;
        z[x] = true;
        int j = head[x];
        while (j >= 0) {
            int y = dst[j];
            dfs(y);
            j = nx[j];
        }
    }

    int n, m;
    int[] head;
    int[] nx;
    int[] dst;
    boolean[] z;
    int last;
    int[] p;
    int pn;

    BufferedReader br;
    PrintWriter out;

    StringTokenizer st;

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

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

    public static void main(String[] args) throws IOException {
        new D().run();
    }

    private void run() throws IOException {
        solve();
        out.close();
    }

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
                colors[i].v = i;
            }
            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new IdentityHashMap<>(0);
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            LongHashMap map = new LongHashMap(q, false);
            for (int i = 0; i < q; i++) {
                int aId = in.readInt();
                int bId = in.readInt();
                long key = DigitUtils.asLong(Math.min(aId, bId),
                        Math.max(aId, bId));
                int sum = (int) map.getOrDefault(key, -1);
                if (sum < 0) {
                    sum = 0;
                    Map<Color, Node> a = maps[aId];
                    Map<Color, Node> b = maps[bId];
                    if (a.size() > b.size()) {
                        Map<Color, Node> tmp = a;
                        a = b;
                        b = tmp;
                    }

                    for (Map.Entry<Color, Node> entry : a.entrySet()) {
                        Node x = entry.getValue();
                        Node y = b.get(entry.getKey());
                        if (y != null && y.find() == x.find()) {
                            sum++;
                        }
                    }
                    map.put(key, sum);
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class Color implements Comparable<Color> {
        int v;

        public int compareTo(Color o) {
            return Integer.compare(v, o.v);
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static interface LongEntryIterator {
        boolean hasNext();

        void next();

        long getEntryKey();

        long getEntryValue();

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class DigitUtils {
        private static long mask32 = (1L << 32) - 1;

        private DigitUtils() {
        }

        public static long asLong(int high, int low) {
            return ((((long) high)) << 32) | (((long) low) & mask32);
        }

    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }

    static class LongHashMap {
        private int[] slot;
        private int[] next;
        private long[] keys;
        private long[] values;
        private int alloc;
        private boolean[] removed;
        private int mask;
        private int size;
        private boolean rehash;

        public LongHashMap(int cap, boolean rehash) {
            this.mask = (1 << (32 - Integer.numberOfLeadingZeros(cap - 1))) - 1;
            slot = new int[mask + 1];
            next = new int[cap + 1];
            keys = new long[cap + 1];
            values = new long[cap + 1];
            removed = new boolean[cap + 1];
            this.rehash = rehash;
        }

        private void doubleCapacity() {
            int newSize = Math.max(next.length + 10, next.length * 2);
            next = Arrays.copyOf(next, newSize);
            keys = Arrays.copyOf(keys, newSize);
            values = Arrays.copyOf(values, newSize);
            removed = Arrays.copyOf(removed, newSize);
        }

        public void alloc() {
            alloc++;
            if (alloc >= next.length) {
                doubleCapacity();
            }
            next[alloc] = 0;
            removed[alloc] = false;
            size++;
        }

        private void rehash() {
            int[] newSlots = new int[Math.max(16, slot.length * 2)];
            int newMask = newSlots.length - 1;
            for (int i = 0; i < slot.length; i++) {
                if (slot[i] == 0) {
                    continue;
                }
                int head = slot[i];
                while (head != 0) {
                    int n = next[head];
                    int s = hash(keys[head]) & newMask;
                    next[head] = newSlots[s];
                    newSlots[s] = head;
                    head = n;
                }
            }
            this.slot = newSlots;
            this.mask = newMask;
        }

        private int hash(long x) {
            int h = Long.hashCode(x);
            return h ^ (h >>> 16);
        }

        public void put(long x, long y) {
            put(x, y, true);
        }

        public void put(long x, long y, boolean cover) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                alloc();
                slot[s] = alloc;
                keys[alloc] = x;
                values[alloc] = y;
            } else {
                int index = findIndexOrLastEntry(s, x);
                if (keys[index] != x) {
                    alloc();
                    next[index] = alloc;
                    keys[alloc] = x;
                    values[alloc] = y;
                } else if (cover) {
                    values[index] = y;
                }
            }
            if (rehash && size >= slot.length) {
                rehash();
            }
        }

        public long getOrDefault(long x, long def) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                return def;
            }
            int index = findIndexOrLastEntry(s, x);
            return keys[index] == x ? values[index] : def;
        }

        private int findIndexOrLastEntry(int s, long x) {
            int iter = slot[s];
            while (keys[iter] != x) {
                if (next[iter] != 0) {
                    iter = next[iter];
                } else {
                    return iter;
                }
            }
            return iter;
        }

        public LongEntryIterator iterator() {
            return new LongEntryIterator() {
                int index = 1;
                int readIndex = -1;

                public boolean hasNext() {
                    while (index <= alloc && removed[index]) {
                        index++;
                    }
                    return index <= alloc;
                }

                public long getEntryKey() {
                    return keys[readIndex];
                }

                public long getEntryValue() {
                    return values[readIndex];
                }

                public void next() {
                    if (!hasNext()) {
                        throw new IllegalStateException();
                    }
                    readIndex = index;
                    index++;
                }
            };
        }

        public String toString() {
            LongEntryIterator iterator = iterator();
            StringBuilder builder = new StringBuilder("{");
            while (iterator.hasNext()) {
                iterator.next();
                builder.append(iterator.getEntryKey()).append("->").append(iterator.getEntryValue()).append(',');
            }
            if (builder.charAt(builder.length() - 1) == ',') {
                builder.setLength(builder.length() - 1);
            }
            builder.append('}');
            return builder.toString();
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.IdentityHashMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
            }
            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new IdentityHashMap<>(0);
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            for (int i = 0; i < q; i++) {
                Map<Color, Node> a = maps[in.readInt()];
                Map<Color, Node> b = maps[in.readInt()];
                if (a.size() > b.size()) {
                    Map<Color, Node> tmp = a;
                    a = b;
                    b = tmp;
                }
                int sum = 0;
                for (Map.Entry<Color, Node> entry : a.entrySet()) {
                    Node x = entry.getValue();
                    Node y = b.get(entry.getKey());
                    if (y != null && y.find() == x.find()) {
                        sum++;
                    }
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Color {
    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
            }
            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new IdentityHashMap<>();
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            LongHashMap map = new LongHashMap(q, false);
            for (int i = 0; i < q; i++) {
                int aId = in.readInt();
                int bId = in.readInt();
                long key = DigitUtils.asLong(Math.min(aId, bId),
                        Math.max(aId, bId));
                int sum = (int) map.getOrDefault(key, -1);
                if (sum < 0) {
                    sum = 0;
                    Map<Color, Node> a = maps[aId];
                    Map<Color, Node> b = maps[bId];
                    if (a.size() > b.size()) {
                        Map<Color, Node> tmp = a;
                        a = b;
                        b = tmp;
                    }

                    for (Map.Entry<Color, Node> entry : a.entrySet()) {
                        Node x = entry.getValue();
                        Node y = b.get(entry.getKey());
                        if (y != null && y.find() == x.find()) {
                            sum++;
                        }
                    }
                    map.put(key, sum);
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class Color {
    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static interface LongEntryIterator {
        boolean hasNext();

        void next();

        long getEntryKey();

        long getEntryValue();

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class DigitUtils {
        private static long mask32 = (1L << 32) - 1;

        private DigitUtils() {
        }

        public static long asLong(int high, int low) {
            return ((((long) high)) << 32) | (((long) low) & mask32);
        }

    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }

    static class LongHashMap {
        private int[] slot;
        private int[] next;
        private long[] keys;
        private long[] values;
        private int alloc;
        private boolean[] removed;
        private int mask;
        private int size;
        private boolean rehash;

        public LongHashMap(int cap, boolean rehash) {
            this.mask = (1 << (32 - Integer.numberOfLeadingZeros(cap - 1))) - 1;
            slot = new int[mask + 1];
            next = new int[cap + 1];
            keys = new long[cap + 1];
            values = new long[cap + 1];
            removed = new boolean[cap + 1];
            this.rehash = rehash;
        }

        private void doubleCapacity() {
            int newSize = Math.max(next.length + 10, next.length * 2);
            next = Arrays.copyOf(next, newSize);
            keys = Arrays.copyOf(keys, newSize);
            values = Arrays.copyOf(values, newSize);
            removed = Arrays.copyOf(removed, newSize);
        }

        public void alloc() {
            alloc++;
            if (alloc >= next.length) {
                doubleCapacity();
            }
            next[alloc] = 0;
            removed[alloc] = false;
            size++;
        }

        private void rehash() {
            int[] newSlots = new int[Math.max(16, slot.length * 2)];
            int newMask = newSlots.length - 1;
            for (int i = 0; i < slot.length; i++) {
                if (slot[i] == 0) {
                    continue;
                }
                int head = slot[i];
                while (head != 0) {
                    int n = next[head];
                    int s = hash(keys[head]) & newMask;
                    next[head] = newSlots[s];
                    newSlots[s] = head;
                    head = n;
                }
            }
            this.slot = newSlots;
            this.mask = newMask;
        }

        private int hash(long x) {
            int h = Long.hashCode(x);
            return h ^ (h >>> 16);
        }

        public void put(long x, long y) {
            put(x, y, true);
        }

        public void put(long x, long y, boolean cover) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                alloc();
                slot[s] = alloc;
                keys[alloc] = x;
                values[alloc] = y;
            } else {
                int index = findIndexOrLastEntry(s, x);
                if (keys[index] != x) {
                    alloc();
                    next[index] = alloc;
                    keys[alloc] = x;
                    values[alloc] = y;
                } else if (cover) {
                    values[index] = y;
                }
            }
            if (rehash && size >= slot.length) {
                rehash();
            }
        }

        public long getOrDefault(long x, long def) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                return def;
            }
            int index = findIndexOrLastEntry(s, x);
            return keys[index] == x ? values[index] : def;
        }

        private int findIndexOrLastEntry(int s, long x) {
            int iter = slot[s];
            while (keys[iter] != x) {
                if (next[iter] != 0) {
                    iter = next[iter];
                } else {
                    return iter;
                }
            }
            return iter;
        }

        public LongEntryIterator iterator() {
            return new LongEntryIterator() {
                int index = 1;
                int readIndex = -1;

                public boolean hasNext() {
                    while (index <= alloc && removed[index]) {
                        index++;
                    }
                    return index <= alloc;
                }

                public long getEntryKey() {
                    return keys[readIndex];
                }

                public long getEntryValue() {
                    return values[readIndex];
                }

                public void next() {
                    if (!hasNext()) {
                        throw new IllegalStateException();
                    }
                    readIndex = index;
                    index++;
                }
            };
        }

        public String toString() {
            LongEntryIterator iterator = iterator();
            StringBuilder builder = new StringBuilder("{");
            while (iterator.hasNext()) {
                iterator.next();
                builder.append(iterator.getEntryKey()).append("->").append(iterator.getEntryValue()).append(',');
            }
            if (builder.charAt(builder.length() - 1) == ',') {
                builder.setLength(builder.length() - 1);
            }
            builder.append('}');
            return builder.toString();
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.IdentityHashMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
            }
            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new IdentityHashMap<>();
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            for (int i = 0; i < q; i++) {
                Map<Color, Node> a = maps[in.readInt()];
                Map<Color, Node> b = maps[in.readInt()];
                if (a.size() > b.size()) {
                    Map<Color, Node> tmp = a;
                    a = b;
                    b = tmp;
                }
                int sum = 0;
                for (Map.Entry<Color, Node> entry : a.entrySet()) {
                    Node x = entry.getValue();
                    Node y = b.get(entry.getKey());
                    if (y != null && y.find() == x.find()) {
                        sum++;
                    }
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Color {
    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.TreeMap;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
                colors[i].v = i;
            }

            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new TreeMap<>();
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            for (int i = 0; i < q; i++) {
                Map<Color, Node> a = maps[in.readInt()];
                Map<Color, Node> b = maps[in.readInt()];
                if (a.size() > b.size()) {
                    Map<Color, Node> tmp = a;
                    a = b;
                    b = tmp;
                }
                int sum = 0;
                for (Map.Entry<Color, Node> entry : a.entrySet()) {
                    Node x = entry.getValue();
                    Node y = b.get(entry.getKey());
                    if (y != null && y.find() == x.find()) {
                        sum++;
                    }
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Color implements Comparable<Color> {
        int v;

        public int compareTo(Color o) {
            return Integer.compare(v, o.v);
        }

    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.TreeMap;
import java.util.Map;
import java.io.Closeable;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DMrKitayutasColorfulGraph solver = new DMrKitayutasColorfulGraph();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DMrKitayutasColorfulGraph {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int m = in.readInt();
            Color[] colors = new Color[m + 1];
            for (int i = 1; i <= m; i++) {
                colors[i] = new Color();
                colors[i].v = i;
            }
            Map<Color, Node>[] maps = new Map[n + 1];
            for (int i = 1; i <= n; i++) {
                maps[i] = new TreeMap<>();
            }

            for (int i = 0; i < m; i++) {
                int a = in.readInt();
                int b = in.readInt();
                int c = in.readInt();
                Node.merge(get(maps[a], colors[c]), get(maps[b], colors[c]));
            }

            int q = in.readInt();
            LongHashMap map = new LongHashMap(q, false);
            for (int i = 0; i < q; i++) {
                int aId = in.readInt();
                int bId = in.readInt();
                long key = DigitUtils.asLong(Math.min(aId, bId),
                        Math.max(aId, bId));
                int sum = (int) map.getOrDefault(key, -1);
                if (sum < 0) {
                    sum = 0;
                    Map<Color, Node> a = maps[aId];
                    Map<Color, Node> b = maps[bId];
                    if (a.size() > b.size()) {
                        Map<Color, Node> tmp = a;
                        a = b;
                        b = tmp;
                    }

                    for (Map.Entry<Color, Node> entry : a.entrySet()) {
                        Node x = entry.getValue();
                        Node y = b.get(entry.getKey());
                        if (y != null && y.find() == x.find()) {
                            sum++;
                        }
                    }
                    map.put(key, sum);
                }
                out.println(sum);
            }
        }

        Node get(Map<Color, Node> map, Color c) {
            Node node = map.get(c);
            if (node == null) {
                node = new Node();
                map.put(c, node);
            }
            return node;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 20];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static interface LongEntryIterator {
        boolean hasNext();

        void next();

        long getEntryKey();

        long getEntryValue();

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class DigitUtils {
        private static long mask32 = (1L << 32) - 1;

        private DigitUtils() {
        }

        public static long asLong(int high, int low) {
            return ((((long) high)) << 32) | (((long) low) & mask32);
        }

    }

    static class Node {
        int rank;
        Node p = this;

        Node find() {
            return p.p == p ? p : (p = p.find());
        }

        static void merge(Node a, Node b) {
            a = a.find();
            b = b.find();
            if (a == b) {
                return;
            }
            if (a.rank == b.rank) {
                a.rank++;
            }
            if (a.rank > b.rank) {
                b.p = a;
            } else {
                a.p = b;
            }
        }

    }

    static class Color implements Comparable<Color> {
        int v;

        public int compareTo(Color o) {
            return Integer.compare(v, o.v);
        }

    }

    static class LongHashMap {
        private int[] slot;
        private int[] next;
        private long[] keys;
        private long[] values;
        private int alloc;
        private boolean[] removed;
        private int mask;
        private int size;
        private boolean rehash;

        public LongHashMap(int cap, boolean rehash) {
            this.mask = (1 << (32 - Integer.numberOfLeadingZeros(cap - 1))) - 1;
            slot = new int[mask + 1];
            next = new int[cap + 1];
            keys = new long[cap + 1];
            values = new long[cap + 1];
            removed = new boolean[cap + 1];
            this.rehash = rehash;
        }

        private void doubleCapacity() {
            int newSize = Math.max(next.length + 10, next.length * 2);
            next = Arrays.copyOf(next, newSize);
            keys = Arrays.copyOf(keys, newSize);
            values = Arrays.copyOf(values, newSize);
            removed = Arrays.copyOf(removed, newSize);
        }

        public void alloc() {
            alloc++;
            if (alloc >= next.length) {
                doubleCapacity();
            }
            next[alloc] = 0;
            removed[alloc] = false;
            size++;
        }

        private void rehash() {
            int[] newSlots = new int[Math.max(16, slot.length * 2)];
            int newMask = newSlots.length - 1;
            for (int i = 0; i < slot.length; i++) {
                if (slot[i] == 0) {
                    continue;
                }
                int head = slot[i];
                while (head != 0) {
                    int n = next[head];
                    int s = hash(keys[head]) & newMask;
                    next[head] = newSlots[s];
                    newSlots[s] = head;
                    head = n;
                }
            }
            this.slot = newSlots;
            this.mask = newMask;
        }

        private int hash(long x) {
            int h = Long.hashCode(x);
            return h ^ (h >>> 16);
        }

        public void put(long x, long y) {
            put(x, y, true);
        }

        public void put(long x, long y, boolean cover) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                alloc();
                slot[s] = alloc;
                keys[alloc] = x;
                values[alloc] = y;
            } else {
                int index = findIndexOrLastEntry(s, x);
                if (keys[index] != x) {
                    alloc();
                    next[index] = alloc;
                    keys[alloc] = x;
                    values[alloc] = y;
                } else if (cover) {
                    values[index] = y;
                }
            }
            if (rehash && size >= slot.length) {
                rehash();
            }
        }

        public long getOrDefault(long x, long def) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                return def;
            }
            int index = findIndexOrLastEntry(s, x);
            return keys[index] == x ? values[index] : def;
        }

        private int findIndexOrLastEntry(int s, long x) {
            int iter = slot[s];
            while (keys[iter] != x) {
                if (next[iter] != 0) {
                    iter = next[iter];
                } else {
                    return iter;
                }
            }
            return iter;
        }

        public LongEntryIterator iterator() {
            return new LongEntryIterator() {
                int index = 1;
                int readIndex = -1;

                public boolean hasNext() {
                    while (index <= alloc && removed[index]) {
                        index++;
                    }
                    return index <= alloc;
                }

                public long getEntryKey() {
                    return keys[readIndex];
                }

                public long getEntryValue() {
                    return values[readIndex];
                }

                public void next() {
                    if (!hasNext()) {
                        throw new IllegalStateException();
                    }
                    readIndex = index;
                    index++;
                }
            };
        }

        public String toString() {
            LongEntryIterator iterator = iterator();
            StringBuilder builder = new StringBuilder("{");
            while (iterator.hasNext()) {
                iterator.next();
                builder.append(iterator.getEntryKey()).append("->").append(iterator.getEntryValue()).append(',');
            }
            if (builder.charAt(builder.length() - 1) == ',') {
                builder.setLength(builder.length() - 1);
            }
            builder.append('}');
            return builder.toString();
        }

    }
}


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

public class D {

    FastScanner in;
    PrintWriter out;

    int SQRT = 200;

    void solve() {
        int n = in.nextInt(), m = in.nextInt();
        Edge[] edges = new Edge[m];
        int[] deg = new int[n];
        for (int i = 0; i < m; i++) {
            edges[i] = new Edge(in.nextInt() - 1, in.nextInt() - 1,
                    in.nextInt());
            deg[edges[i].from]++;
            deg[edges[i].to]++;
        }
        Arrays.sort(edges);

        int[][] graph = new int[n][];
        int[][] col = new int[n][];
        for (int i = 0; i < n; i++) {
            graph[i] = new int[deg[i]];
            col[i] = new int[deg[i]];
        }
        Arrays.fill(deg, 0);
        for (int i = 0; i < m; i++) {
            int fr = edges[i].from, to = edges[i].to;
            graph[fr][deg[fr]] = to;
            col[fr][deg[fr]++] = edges[i].col;

            graph[to][deg[to]] = fr;
            col[to][deg[to]++] = edges[i].col;
        }
        int[] begin = new int[n];

        int qs = in.nextInt();
        Map<Long, Integer> qId = new HashMap<Long, Integer>();
        int[] q1 = new int[qs], q2 = new int[qs];
        int[] unique1 = new int[qs], unique2 = new int[qs];
        int uniqs = 0;
        for (int i = 0; i < qs; i++) {
            q1[i] = in.nextInt() - 1;
            q2[i] = in.nextInt() - 1;
            if (q1[i] > q2[i]) {
                int tmp = q1[i];
                q1[i] = q2[i];
                q2[i] = tmp;
            }

            long hash = 1L * q1[i] * n + q2[i];
            if (qId.containsKey(hash)) {
                continue;
            } else {
                qId.put(hash, uniqs);
                unique1[uniqs] = q1[i];
                unique2[uniqs] = q2[i];
                uniqs++;
            }
        }

        long[] keys = new long[uniqs];
        int[] ids = new int[uniqs];
        {
            int tmp = 0;
            for (long l : qId.keySet()) {
                keys[tmp++] = l;
            }
            Arrays.sort(keys);
            for (int i = 0; i < uniqs; i++) {
                ids[i] = qId.get(keys[i]);
            }
        }

        int[] result = new int[uniqs];

        DSU dsu = new DSU(n);
        int[] all = new int[2 * SQRT];
        int[] queue = new int[2 * SQRT];

        int[] lastColor = new int[n];

        for (int l = 0; l < m;) {
            int r = l;
            int curCol = edges[l].col;
            while (r < m && edges[r].col == curCol) {
                r++;
            }

            int size = r - l;
            if (size < SQRT) {
                int ptr = 0;
                for (int t = l; t < r; t++) {
                    all[ptr++] = edges[t].from;
                    all[ptr++] = edges[t].to;
                }
                Arrays.sort(all, 0, ptr);

                for (int ll = 0; ll < ptr; ll++) {
                    if (ll > 0 && all[ll] == all[ll - 1]) {
                        continue;
                    }
                    int start = all[ll];
                    if (lastColor[start] == curCol) {
                        continue;
                    }

                    int head = 0, tail = 0;
                    queue[tail++] = start;
                    lastColor[start] = curCol;

                    while (head < tail) {
                        int cur = queue[head++];
                        int beg = begin[cur];

                        int[] curG = graph[cur], curC = col[cur];
                        while (beg < curC.length && curC[beg] == curCol) {
                            int nxt = curG[beg++];
                            if (lastColor[nxt] < curCol) {
                                lastColor[nxt] = curCol;
                                queue[tail++] = nxt;
                            }
                        }
                    }

                    for (int fst = 0; fst < tail; fst++) {
                        int v1 = queue[fst];
                        for (int snd = fst + 1; snd < tail; snd++) {
                            int v2 = queue[snd];
                            long hash;
                            if (v1 < v2) {
                                hash = 1L * v1 * n + v2;
                            } else {
                                hash = 1L * v2 * n + v1;
                            }

                            int left = -1, right = uniqs;
                            while (left < right - 1) {
                                int mid = (left + right) >>> 1;
                                if (hash >= keys[mid]) {
                                    left = mid;
                                } else {
                                    right = mid;
                                }
                            }
                            if (left >= 0 && keys[left] == hash) {
                                result[ids[left]]++;
                            }
                        }
                    }
                }

            } else {
                dsu.clear();
                for (int t = l; t < r; t++) {
                    dsu.unite(edges[t].from, edges[t].to);
                }

                for (int i = 0; i < uniqs; i++) {
                    if (dsu.get(unique1[i]) == dsu.get(unique2[i])) {
                        result[i]++;
                    }
                }
            }

            for (int t = l; t < r; t++) {
                begin[edges[t].from]++;
                begin[edges[t].to]++;
            }
            l = r;
        }

        for (int i = 0; i < qs; i++) {
            long hash = 1L * q1[i] * n + q2[i];
            out.println(result[qId.get(hash)]);
        }
    }

    static class Edge implements Comparable<Edge> {
        int from, to, col;

        public Edge(int from, int to, int col) {
            this.from = from;
            this.to = to;
            this.col = col;
        }

        @Override
        public int compareTo(Edge o) {
            return col - o.col;
        }

        @Override
        public String toString() {
            return "Edge [from=" + from + ", to=" + to + ", col=" + col + "]";
        }

    }

    static class DSU {
        int[] p, r;

        public DSU(int n) {
            p = new int[n];
            r = new int[n];
            for (int i = 0; i < n; i++) {
                p[i] = i;
            }
        }

        int get(int u) {
            if (p[u] == u) {
                return u;
            }
            return p[u] = get(p[u]);
        }

        void clear() {
            Arrays.fill(r, 0);
            for (int i = 0; i < p.length; i++) {
                p[i] = i;
            }
        }

        void unite(int u, int v) {
            u = get(u);
            v = get(v);
            if (u == v) {
                return;
            }

            if (r[u] == r[v]) {
                r[u]++;
            }
            if (r[u] > r[v]) {
                p[u] = v;
            } else {
                p[v] = u;
            }
        }
    }

    void run() {
        in = new FastScanner();
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

    public static void main(String[] args) {
        new D().run();
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();

        int[][] edges = new int[m][3];
        for (int i = 0 ; i < m ; i++) {
            // u,v,color
            edges[i][0] = in.nextInt()-1;
            edges[i][1] = in.nextInt()-1;
            edges[i][2] = in.nextInt()-1;
        }
        Arrays.sort(edges, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[2] - o2[2];
            }
        });

        int[] cdeg = new int[n];
        int[][] colorToV = new int[m][];
        UnionFind[] ufs = new UnionFind[m];

        int[] tempV = new int[n];
        boolean[] visitedV = new boolean[n];
        for (int fr = 0 ; fr < m ; ) {
            int to = fr;
            while (to < m && edges[to][2] == edges[fr][2]) {
                to++;
            }
            int cid = edges[fr][2];
            int vi = 0;
            for (int i = fr ; i < to ; i++) {
                int a = edges[i][0];
                int b = edges[i][1];
                if (!visitedV[a]) {
                    visitedV[a] = true;
                    tempV[vi++] = a;
                }
                if (!visitedV[b]) {
                    visitedV[b] = true;
                    tempV[vi++] = b;
                }
            }

            colorToV[cid] = Arrays.copyOf(tempV, vi);
            Arrays.sort(colorToV[cid]);
            for (int v : colorToV[cid]) {
                cdeg[v]++;
            }

            ufs[cid] = new UnionFind(vi);
            for (int i = fr ; i < to ; i++) {
                int a = edges[i][0];
                int b = edges[i][1];
                int ai = Arrays.binarySearch(colorToV[cid], a);
                int bi = Arrays.binarySearch(colorToV[cid], b);
                ufs[cid].unite(ai, bi);
            }

            for (int i = fr ; i < to ; i++) {
                int a = edges[i][0];
                int b = edges[i][1];
                visitedV[a] = false;
                visitedV[b] = false;
            }
            fr = to;
        }

        int[][] vToColor = new int[n][];
        for (int i = 0 ; i < n ; i++) {
            vToColor[i] = new int[cdeg[i]];
        }
        for (int i = 0 ; i < m ; i++) {
            if (colorToV[i] != null) {
                for (int v : colorToV[i]) {
                    vToColor[v][--cdeg[v]] = i;
                }
            }
        }

        Map<Long,Integer> memo = new HashMap<>();
        for (int q = in.nextInt() ; q >= 1 ; --q) {
            int a = in.nextInt()-1;
            int b = in.nextInt()-1;
            if (vToColor[a].length > vToColor[b].length) {
                int tmp = a;
                a = b;
                b = tmp;
            }
            long pairID = a*1000000L+b;
            if (memo.containsKey(pairID)) {
                out.println(memo.get(pairID));
                continue;
            }

            int cnt = 0;
            for (int col : vToColor[a]) {
                int ai = Arrays.binarySearch(colorToV[col], a);
                int bi = Arrays.binarySearch(colorToV[col], b);
                if (ai < 0 || bi < 0) {
                    continue;
                }
                if (ufs[col].issame(ai, bi)) {
                    cnt++;
                }
            }
            memo.put(pairID, cnt);
            out.println(cnt);
        }

        out.flush();
    }

    static class UnionFind {
        int[] parent, rank;
        UnionFind(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int i = 0 ; i < n ; i++) {
                parent[i] = i;
                rank[i] = 0;
            }
        }

        int find(int x) {
            if (parent[x] == x) {
                return x;
            }
            parent[x] = find(parent[x]);
            return parent[x];
        }

        void unite(int x, int y) {
            x = find(x);
            y = find(y);
            if (x == y) {
                return;
            }
            if (rank[x] < rank[y]) {
                parent[x] = y;
            } else {
                parent[y] = x;
                if (rank[x] == rank[y]) {
                    rank[x]++;
                }
            }
        }
        boolean issame(int x, int y) {
            return (find(x) == find(y));
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

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

        private int next() {
            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 = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = next();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

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

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

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();

        Set<Integer>[] vColors = new Set[n];
        Map<Integer,Integer> colorIds = new HashMap<>();
        Map<Integer,Map<Integer,Integer>> colorV = new HashMap<>();

        for (int i = 0 ; i < n ; i++) {
            vColors[i] = new HashSet<>();
        }

        int[][] edges = new int[m][];
        for (int i = 0 ; i < m ; i++) {
            int a = in.nextInt()-1;
            int b = in.nextInt()-1;
            int c = in.nextInt()-1;
            edges[i] = new int[]{a, b, c};
            if (!colorIds.containsKey(c)) {
                int newcid = colorIds.size();
                colorIds.put(c, newcid);
                colorV.put(newcid, new HashMap<>());
            }
            int cid = colorIds.get(c);
            vColors[a].add(cid);
            vColors[b].add(cid);

            Map<Integer,Integer> vmap = colorV.get(cid);
            if (!vmap.containsKey(a)) {
                vmap.put(a, vmap.size());
            }
            if (!vmap.containsKey(b)) {
                vmap.put(b, vmap.size());
            }
        }

        UnionFind[] ufs = new UnionFind[colorIds.size()];
        for (int c : colorIds.keySet()) {
            int cid = colorIds.get(c);
            Map<Integer,Integer> vmap = colorV.get(cid);
            ufs[cid] = new UnionFind(vmap.size());
        }
        for (int i = 0 ; i < m ; i++) {
            int a = edges[i][0];
            int b = edges[i][1];
            int c = edges[i][2];
            int cid = colorIds.get(c);
            Map<Integer,Integer> vmap = colorV.get(cid);
            int ai = vmap.get(a);
            int bi = vmap.get(b);
            ufs[cid].unite(ai, bi);
        }

        Map<Long,Integer> memo = new HashMap<>();

        int q = in.nextInt();
        while (--q >= 0) {
            int a = in.nextInt()-1;
            int b = in.nextInt()-1;
            if (vColors[a].size() > vColors[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            long ab = a*1000000L+b;
            if (!memo.containsKey(ab)) {
                int cnt = 0;
                for (int cid : vColors[a]) {
                    Map<Integer,Integer> vmap = colorV.get(cid);
                    int ai = vmap.get(a);
                    if (vmap.containsKey(b)) {
                        int bi = vmap.get(b);
                        if (ufs[cid].issame(ai, bi)) {
                            cnt++;
                        }
                    }
                }
                memo.put(ab, cnt);
            }
            out.println(memo.get(ab));
        }
        out.flush();
    }

    static class UnionFind {
        int[] parent, rank;
        UnionFind(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int i = 0 ; i < n ; i++) {
                parent[i] = i;
                rank[i] = 0;
            }
        }

        int find(int x) {
            if (parent[x] == x) {
                return x;
            }
            parent[x] = find(parent[x]);
            return parent[x];
        }

        void unite(int x, int y) {
            x = find(x);
            y = find(y);
            if (x == y) {
                return;
            }
            if (rank[x] < rank[y]) {
                parent[x] = y;
            } else {
                parent[y] = x;
                if (rank[x] == rank[y]) {
                    rank[x]++;
                }
            }
        }
        boolean issame(int x, int y) {
            return (find(x) == find(y));
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

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

        private int next() {
            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 = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = next();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

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

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

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();

        Set<Integer>[] vColors = new Set[n];
        Map<Integer,Integer> colorIds = new HashMap<>();
        Map<Integer,Map<Integer,Integer>> colorV = new HashMap<>();

        for (int i = 0 ; i < n ; i++) {
            vColors[i] = new HashSet<>();
        }

        int[][] edges = new int[m][];
        for (int i = 0 ; i < m ; i++) {
            int a = in.nextInt()-1;
            int b = in.nextInt()-1;
            int c = in.nextInt()-1;
            edges[i] = new int[]{a, b, c};
            if (!colorIds.containsKey(c)) {
                int newcid = colorIds.size();
                colorIds.put(c, newcid);
                colorV.put(newcid, new HashMap<>());
            }
            int cid = colorIds.get(c);
            vColors[a].add(cid);
            vColors[b].add(cid);

            Map<Integer,Integer> vmap = colorV.get(cid);
            if (!vmap.containsKey(a)) {
                vmap.put(a, vmap.size());
            }
            if (!vmap.containsKey(b)) {
                vmap.put(b, vmap.size());
            }
        }

        UnionFind[] ufs = new UnionFind[colorIds.size()];
        for (int c : colorIds.keySet()) {
            int cid = colorIds.get(c);
            Map<Integer,Integer> vmap = colorV.get(c);
            ufs[cid] = new UnionFind(vmap.size());
        }
        for (int i = 0 ; i < m ; i++) {
            int a = edges[i][0];
            int b = edges[i][1];
            int c = edges[i][2];
            int cid = colorIds.get(c);
            Map<Integer,Integer> vmap = colorV.get(cid);
            int ai = vmap.get(a);
            int bi = vmap.get(b);
            ufs[cid].unite(ai, bi);
        }

        Map<Long,Integer> memo = new HashMap<>();

        int q = in.nextInt();
        while (--q >= 0) {
            int a = in.nextInt()-1;
            int b = in.nextInt()-1;
            if (vColors[a].size() > vColors[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            long ab = a*1000000L+b;
            if (!memo.containsKey(ab)) {
                int cnt = 0;
                for (int cid : vColors[a]) {
                    int ai = colorV.get(cid).get(a);
                    if (colorV.get(cid).containsKey(b)) {
                        int bi = colorV.get(cid).get(b);
                        if (ufs[cid].issame(ai, bi)) {
                            cnt++;
                        }
                    }
                }
                memo.put(ab, cnt);
            }
            out.println(memo.get(ab));
        }
        out.flush();
    }

    static class UnionFind {
        int[] parent, rank;
        UnionFind(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int i = 0 ; i < n ; i++) {
                parent[i] = i;
                rank[i] = 0;
            }
        }

        int find(int x) {
            if (parent[x] == x) {
                return x;
            }
            parent[x] = find(parent[x]);
            return parent[x];
        }

        void unite(int x, int y) {
            x = find(x);
            y = find(y);
            if (x == y) {
                return;
            }
            if (rank[x] < rank[y]) {
                parent[x] = y;
            } else {
                parent[y] = x;
                if (rank[x] == rank[y]) {
                    rank[x]++;
                }
            }
        }
        boolean issame(int x, int y) {
            return (find(x) == find(y));
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

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

        private int next() {
            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 = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = next();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

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

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

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}