import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        ArrayList<DSU>[] cntDSU;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt(), sc.nextInt());
            ribs[r.c].add(r);
        }

        cntDSU = new ArrayList[n + 1];
        for (int v = 1; v <= n; v++) {
            cntDSU[v] = new ArrayList<>(1);
        }
        for (int c = 1; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            for (Integer v : dsu.map.keySet()) {
                cntDSU[v].add(dsu);
            }
        }

        int Q = sc.nextInt();
        Map<String, Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (cntDSU[a].size() > cntDSU[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            Integer get = answers.get(a + "," + b);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (DSU dsu : cntDSU[a]) {
                if (dsu.isConnected(a, b)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(a + "," + b, curAns);
            answers.put(b + "," + a, curAns);
        }
    }
}

final class DSU {

    TreeMap<Integer, Integer> map;
    int[] p;
    int[] sz;

    boolean isConnected(Integer a, Integer b) {
        a = map.get(a);
        b = map.get(b);
        if (a == null || b == null) {
            return false;
        }
        return getParent(a) == getParent(b);
    }

    public DSU(ArrayList<Rib> arr) {
        map = new TreeMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getParent(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getParent(p[v]);
    }

    void unit(int a, int b) {
        a = getParent(a);
        b = getParent(b);
        if (sz[a] < sz[b]) {
            int t = a;
            a = b;
            b = t;
        }
        p[b] = a;
        sz[a] += sz[b];
    }

}

class Rib {

    int a, b, c;

    public Rib(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

}


import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        ArrayList<DSU>[] cntDSU;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt(), sc.nextInt());
            ribs[r.c].add(r);
        }

        cntDSU = new ArrayList[n + 1];
        for (int v = 1; v <= n; v++) {
            cntDSU[v] = new ArrayList<>();
        }
        for (int c = 1; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            for (Integer v : dsu.map.keySet()) {
                cntDSU[v].add(dsu);
            }
        }

        int Q = sc.nextInt();
        Map<String,Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (cntDSU[a].size() > cntDSU[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            Integer get = answers.get(a+","+b);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (DSU dsu : cntDSU[a]) {
                if (dsu.isConnected(a, b)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(a+","+b, curAns);
            answers.put(b+","+a, curAns);
        }
    }
}

final class DSU {

    Map<Integer, Integer> map;
    int[] p;
    int[] sz;

    boolean isConnected(int a, int b){
        if ( !map.containsKey(a) || !map.containsKey(b) ) {
            return false;
        }
        a = map.get(a);
        b = map.get(b);
        return getParent(a) == getParent(b);
    }

    public DSU(ArrayList<Rib> arr) {
        map = new HashMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getParent(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getParent(p[v]);
    }

    void unit(int a, int b) {
        a = getParent(a);
        b = getParent(b);
        if (sz[a] < sz[b]) {
            unit(b, a);
        } else {
            p[b] = a;
            sz[a] += sz[b];
        }
    }

}

class Rib {

    int a, b, c;

    public Rib(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

}


import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        ArrayList<DSU>[] cntDSU;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt(), sc.nextInt());
            ribs[r.c].add(r);
        }

        cntDSU = new ArrayList[n + 1];
        for (int v = 1; v <= n; v++) {
            cntDSU[v] = new ArrayList<>();
        }
        for (int c = 1; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            for (Rib r : ribs[c]) {
                cntDSU[r.a].add(dsu);
                cntDSU[r.b].add(dsu);
            }
        }

        int Q = sc.nextInt();
        Map<String,Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (cntDSU[a].size() > cntDSU[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            Integer get = answers.get(a+","+b);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (DSU dsu : cntDSU[a]) {
                if (dsu.isConnected(a, b)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(a+","+b, curAns);
            answers.put(b+","+a, curAns);
        }
    }
}

final class DSU {

    Map<Integer, Integer> map;
    int[] p;
    int[] sz;

    boolean isConnected(int a, int b){
        if ( !map.containsKey(a) || !map.containsKey(b) ) {
            return false;
        }
        a = map.get(a);
        b = map.get(b);
        return getP(a) == getP(b);
    }

    public DSU(ArrayList<Rib> arr) {
        map = new HashMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getP(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getP(p[v]);
    }

    void unit(int a, int b) {
        a = getP(a);
        b = getP(b);
        if (sz[a] < sz[b]) {
            unit(b, a);
        } else {
            p[b] = a;
            sz[a] += sz[b];
        }
    }

}

class Rib {

    int a, b, c;

    public Rib(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

}


import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        HashSet<Integer>[] idLeader;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt());
            int c = sc.nextInt();
            ribs[c].add(r);
        }

        idLeader = new HashSet[n + 1];
        for (int v = 1; v <= n; v++) {
            idLeader[v] = new HashSet<>();
        }
        for (int c = 1, id = 0; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            HashMap<Integer, Integer> idLd = new HashMap<>();
            for (Map.Entry<Integer, Integer> e : dsu.map.entrySet()) {
                int v = e.getKey();
                int idV = e.getValue();
                int leader = dsu.getParent(idV);
                if (!idLd.containsKey(leader)) {
                    idLd.put(leader, id++);
                }
                int idLeade = idLd.get(leader);
                idLeader[v].add(idLeade);
            }
        }

        int Q = sc.nextInt();
        HashMap<String, Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (idLeader[a].size() > idLeader[b].size()
                    || idLeader[a].size() == idLeader[b].size() && a > b) {
                int t = a;
                a = b;
                b = t;
            }
            String hashQ = a + "," + b;
            Integer get = answers.get(hashQ);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (Integer x : idLeader[a]) {
                if (idLeader[b].contains(x)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(hashQ, curAns);
        }
    }
}

final class DSU {

    HashMap<Integer, Integer> map;
    int[] p;
    int[] sz;

    public DSU(ArrayList<Rib> arr) {
        map = new HashMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getParent(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getParent(p[v]);
    }

    void unit(int a, int b) {
        a = getParent(a);
        b = getParent(b);
        if (sz[a] < sz[b]) {
            int t = a;
            a = b;
            b = t;
        }
        p[b] = a;
        sz[a] += sz[b];
    }

}

class Rib {

    int a, b;

    public Rib(int a, int b) {
        this.a = a;
        this.b = b;
    }

}


import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        ArrayList<DSU>[] cntDSU;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt(), sc.nextInt());
            ribs[r.c].add(r);
        }

        cntDSU = new ArrayList[n + 1];
        for (int v = 1; v <= n; v++) {
            cntDSU[v] = new ArrayList<>(1);
        }
        for (int c = 1; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            for (Integer v : dsu.map.keySet()) {
                cntDSU[v].add(dsu);
            }
        }

        int Q = sc.nextInt();
        Map<String,Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (cntDSU[a].size() > cntDSU[b].size()) {
                int t = a;
                a = b;
                b = t;
            }
            Integer get = answers.get(a+","+b);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (DSU dsu : cntDSU[a]) {
                if (dsu.isConnected(a, b)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(a+","+b, curAns);
            answers.put(b+","+a, curAns);
        }
    }
}

final class DSU {

    Map<Integer, Integer> map;
    int[] p;
    int[] sz;

    boolean isConnected(int a, int b){
        if ( !map.containsKey(a) || !map.containsKey(b) ) {
            return false;
        }
        a = map.get(a);
        b = map.get(b);
        return getParent(a) == getParent(b);
    }

    public DSU(ArrayList<Rib> arr) {
        map = new TreeMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getParent(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getParent(p[v]);
    }

    void unit(int a, int b) {
        a = getParent(a);
        b = getParent(b);
        if (sz[a] < sz[b]) {
            int t = a;
            a = b;
            b = t;
        }
        p[b] = a;
        sz[a] += sz[b];
    }

}

class Rib {

    int a, b, c;

    public Rib(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

}


import java.awt.Point;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import java.awt.Point;

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

    // https://netbeans.org/kb/73/java/editor-codereference_ru.html#display
    static boolean oj;

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }
//
        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;

        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Main().run();
        //new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

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

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

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void aser(boolean OK) {
        if (!OK) {
            Main.MLE();
//            for(;;);
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    void solve() {
        int n, m;
        ArrayList<Rib>[] ribs;
        Set<Integer>[] idLeader;

        n = sc.nextInt();
        m = sc.nextInt();
        ribs = new ArrayList[m + 1];
        for (int c = 1; c <= m; c++) {
            ribs[c] = new ArrayList<>(1);
        }
        for (int iter = 0; iter < m; iter++) {
            Rib r = new Rib(sc.nextInt(), sc.nextInt());
            int c = sc.nextInt();
            ribs[c].add(r);
        }

        idLeader = new Set[n+1];
        for (int v = 1; v <= n; v++) {
            idLeader[v] = new HashSet<>();
        }
        for (int c = 1, id = 0; c <= m; c++) {
            DSU dsu = new DSU(ribs[c]);
            HashMap<Integer,Integer> idLd = new HashMap<>();
            for (Map.Entry<Integer, Integer> e : dsu.map.entrySet()) {
                int v = e.getKey();
                int idV = e.getValue();
                int leader = dsu.getParent(idV);
                if(!idLd.containsKey(leader))
                    idLd.put(leader, id++);
                int idLeade = idLd.get(leader);
                idLeader[v].add(idLeade);
            }
        }

        int Q = sc.nextInt();
        HashMap<String, Integer> answers = new HashMap<>();
        for (int iter = 0; iter < Q; iter++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            if (idLeader[a].size() > idLeader[b].size() ||
                    idLeader[a].size() == idLeader[b].size() && a > b) {
                int t = a;
                a = b;
                b = t;
            }
            String hashQ = a + "," + b;
            Integer get = answers.get(hashQ);
            if (get != null) {
                out.println(get);
                continue;
            }

            int curAns = 0;
            for (Integer x : idLeader[a]) {
                if (idLeader[b].contains(x)) {
                    ++curAns;
                }
            }
            out.println(curAns);

            answers.put(hashQ, curAns);
        }
    }
}

final class DSU {

    TreeMap<Integer, Integer> map;
    int[] p;
    int[] sz;

    public DSU(ArrayList<Rib> arr) {
        map = new TreeMap<>();
        for (Rib r : arr) {
            if (!map.containsKey(r.a)) {
                map.put(r.a, map.size());
            }
            if (!map.containsKey(r.b)) {
                map.put(r.b, map.size());
            }
        }
        p = new int[map.size()];
        sz = new int[map.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = i;
        }
        for (int i = 0; i < sz.length; i++) {
            sz[i] = 1;
        }
        for (Rib r : arr) {
            int a = map.get(r.a);
            int b = map.get(r.b);
            unit(a, b);
        }
    }

    int getParent(int v) {
        if (p[v] == v) {
            return v;
        }
        return p[v] = getParent(p[v]);
    }

    void unit(int a, int b) {
        a = getParent(a);
        b = getParent(b);
        if (sz[a] < sz[b]) {
            int t = a;
            a = b;
            b = t;
        }
        p[b] = a;
        sz[a] += sz[b];
    }

}

class Rib {

    int a, b;

    public Rib(int a, int b) {
        this.a = a;
        this.b = b;
    }

}


package com.nelearin;

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

//<editor-fold defaultstate="collapsed" desc="Main">
public class Main implements Runnable {

	@Override
	public void run() {
		try {
			Locale.setDefault(Locale.US);
		} catch (Exception ignored) {
		}
		boolean oj = true;
		try {
			oj = System.getProperty("MYLOCAL") == null;
		} catch (Exception ignored) {
		}
//
		if (oj) {
			sc = new FastScanner(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
		} else {
			try {
				sc = new FastScanner(new FileReader("input.txt"));
//                sc = new FastScanner(new FileReader("C:\\Users\\Igor\\Desktop\\e\\tests\\02"));
				out = new PrintWriter(new FileWriter("output.txt"));
			} catch (IOException e) {
				MLE();
			}
		}
		Solver s = new Solver();
		s.mScanner = sc;
		s.mWriter = out;

		s.solve();
		if (!oj) {
			err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
			err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
		}
		out.flush();
	}

	public static void exit() {
		err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
		err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
		out.flush();
		out.close();
		System.exit(0);
	}

	public static void MLE() {
		int[][] arr = new int[1024 * 1024][];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = new int[1024 * 1024];
		}
	}

	public static void main(String[] args) {
		new Main().run();
		//new Thread(null, new Main(), "myThread", 100 * 1024 * 1024).start();
	}

	private static long timeBegin = System.currentTimeMillis();
	private static FastScanner sc;
	private static PrintWriter out;
	private static PrintStream err = System.err;
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

	private BufferedReader mBufferedReader;
	private StringTokenizer mStringTokenizer;

	FastScanner(InputStreamReader reader) {
		mBufferedReader = new BufferedReader(reader);
		mStringTokenizer = new StringTokenizer("");
	}

	private String next() {
		while (!mStringTokenizer.hasMoreElements()) {
			try {
				mStringTokenizer = new StringTokenizer(mBufferedReader.readLine());
			} catch (Exception ex) {
				return null;
			}
		}
		return mStringTokenizer.nextToken();
	}

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

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

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

	String nextLine() {
		try {
			return mBufferedReader.readLine();
		} catch (IOException ex) {
			return null;
		}
	}
}
//</editor-fold>

class Solver {

	void aser(boolean OK) {
		if (!OK) {
			Main.MLE();
//            for(;;);
		}
	}

	FastScanner mScanner;
	PrintWriter mWriter;
	static PrintStream err = System.err;

	void solve() {
		int n, m;
		ArrayList<Pair>[] pairs;
		HashSet<Integer>[] idLeader;

		n = mScanner.nextInt();
		m = mScanner.nextInt();
		pairs = new ArrayList[m + 1];
		for (int c = 1; c <= m; c++) {
			pairs[c] = new ArrayList<>(1);
		}
		for (int iter = 0; iter < m; iter++) {
			Pair r = new Pair(mScanner.nextInt(), mScanner.nextInt());
			int c = mScanner.nextInt();
			pairs[c].add(r);
		}

		idLeader = new HashSet[n + 1];
		for (int v = 1; v <= n; v++) {
			idLeader[v] = new HashSet<>();
		}
		for (int c = 1, id = 0; c <= m; c++) {
			DSU dsu = new DSU(pairs[c]);
			HashMap<Integer, Integer> idLd = new HashMap<>();
			for (Map.Entry<Integer, Integer> e : dsu.map.entrySet()) {
				int v = e.getKey();
				int idV = e.getValue();
				int leader = dsu.getParent(idV);
				if (!idLd.containsKey(leader)) {
					idLd.put(leader, id++);
				}
				int idLeade = idLd.get(leader);
				idLeader[v].add(idLeade);
			}
		}

		int Q = mScanner.nextInt();
		HashMap<String, Integer> answers = new HashMap<>();
		for (int iter = 0; iter < Q; iter++) {
			int a = mScanner.nextInt();
			int b = mScanner.nextInt();
			if (idLeader[a].size() > idLeader[b].size()
					|| idLeader[a].size() == idLeader[b].size() && a > b) {
				int t = a;
				a = b;
				b = t;
			}
			String hashQ = a + "," + b;
			Integer get = answers.get(hashQ);
			if (get != null) {
				mWriter.println(get);
				continue;
			}

			int curAns = 0;
			for (Integer x : idLeader[a]) {
				if (idLeader[b].contains(x)) {
					++curAns;
				}
			}
			mWriter.println(curAns);

			answers.put(hashQ, curAns);
		}
	}
}

final class DSU {
	HashMap<Integer, Integer> map;
	int[] p;
	int[] sz;

	public DSU(ArrayList<Pair> arr) {
		map = new HashMap<>();
		for (Pair r : arr) {
			if (!map.containsKey(r.a)) {
				map.put(r.a, map.size());
			}
			if (!map.containsKey(r.b)) {
				map.put(r.b, map.size());
			}
		}
		p = new int[map.size()];
		sz = new int[map.size()];
		for (int i = 0; i < p.length; i++) {
			p[i] = i;
		}
		for (int i = 0; i < sz.length; i++) {
			sz[i] = 1;
		}
		for (Pair r : arr) {
			int a = map.get(r.a);
			int b = map.get(r.b);
			unit(a, b);
		}
	}

	int getParent(int v) {
		if (p[v] == v) {
			return v;
		}
		return p[v] = getParent(p[v]);
	}

	void unit(int a, int b) {
		a = getParent(a);
		b = getParent(b);
		if (sz[a] < sz[b]) {
			int t = a;
			a = b;
			b = t;
		}
		p[b] = a;
		sz[a] += sz[b];
	}

}

class Pair {

	int a, b;

	public Pair(int a, int b) {
		this.a = a;
		this.b = b;
	}

}


// practice with rainboy
import java.io.*;
import java.util.*;

public class CF506D extends PrintWriter {
	CF506D() { super(System.out); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF506D o = new CF506D(); o.main(); o.flush();
	}

	static final int N = 100000, M = 350;
	static class E {
		int i, j, c;
		E(int i, int j, int c) {
			this.i = i; this.j = j; this.c = c;
		}
	}

	int[] dsu;
	int find(int i) {
		return dsu[i] < 0 ? i : (dsu[i] = find(dsu[i]));
	}
	void join(int i, int j) {
		i = find(i);
		j = find(j);
		if (i == j)
			return;
		if (dsu[i] > dsu[j])
			dsu[i] = j;
		else {
			if (dsu[i] == dsu[j])
				dsu[i]--;
			dsu[j] = i;
		}
	}

	static Random rand = new Random();
	static class V {
		V l, r;
		long key;
		int val, x;
		V(long key, int val) {
			this.key = key; this.val = val;
			x = rand.nextInt();
		}
	}
	V v_, l_, r_;
	void split(V v, long key) {
		if (v == null) {
			v_ = l_ = r_ = null;
		} else if (v.key < key) {
			split(v.r, key);
			v.r = l_; l_ = v;
		} else if (v.key > key) {
			split(v.l, key);
			v.l = r_; r_ = v;
		} else {
			v_ = v; l_ = v.l; r_ = v.r;
			v.l = v.r = null;
		}
	}
	V merge(V u, V v) {
		if (u == null)
			return v;
		if (v == null)
			return u;
		if (u.x <= v.x) {
			u.r = merge(u.r, v);
			return u;
		} else {
			v.l = merge(u, v.l);
			return v;
		}
	}
	long compose(int i, int j) {
		if (i > j) {
			int tmp = i; i = j; j = tmp;
		}
		return (long) i * N + j;
	}
	void add(int i, int j) {
		long key = compose(i, j);
		split(v_, key);
		if (v_ == null)
			v_ = new V(key, 0);
		v_ = merge(l_, merge(v_, r_));
	}
	void update(int i, int j) {
		long key = compose(i, j);
		split(v_, key);
		if (v_ != null)
			v_.val++;
		v_ = merge(l_, merge(v_, r_));
	}
	int query(int i, int j) {
		long key = compose(i, j);
		split(v_, key);
		int val = v_.val;
		v_ = merge(l_, merge(v_, r_));
		return val;
	}

	void main() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		E[] ee = new E[m];
		for (int h = 0; h < m; h++) {
			int i = sc.nextInt() - 1;
			int j = sc.nextInt() - 1;
			int c = sc.nextInt();
			ee[h] = new E(i, j, c);
		}
		Arrays.sort(ee, (e, f) -> e.c - f.c);
		int q = sc.nextInt();
		int[] ii = new int[q];
		int[] jj = new int[q];
		int[] ans = new int[q];
		for (int h = 0; h < q; h++) {
			int i = sc.nextInt() - 1;
			int j = sc.nextInt() - 1;
			ii[h] = i; jj[h] = j;
			add(i, j);
		}
		dsu = new int[n]; Arrays.fill(dsu, -1);
		boolean[] used = new boolean[n];
		int[] qq = new int[n];
		for (int h = 0, h_; h < m; h = h_) {
			h_ = h + 1;
			while (h_ < m && ee[h_].c == ee[h].c)
				h_++;
			int cnt = 0;
			for (int h1 = h; h1 < h_; h1++) {
				int i = ee[h1].i, j = ee[h1].j;
				join(i, j);
				if (!used[i]) {
					used[i] = true;
					qq[cnt++] = i;
				}
				if (!used[j]) {
					used[j] = true;
					qq[cnt++] = j;
				}
			}
			if (h_ - h < M)
				for (int h1 = 0; h1 < cnt; h1++)
					for (int h2 = h1 + 1; h2 < cnt; h2++) {
						int i = qq[h1], j = qq[h2];
						if (find(i) == find(j))
							update(i, j);
					}
			else
				for (int h1 = 0; h1 < q; h1++) {
					int i = ii[h1], j = jj[h1];
					if (find(i) == find(j))
						ans[h1]++;
				}
			for (int h1 = 0; h1 < cnt; h1++) {
				int i = qq[h1];
				used[i] = false;
				dsu[i] = -1;
			}
		}
		for (int h = 0; h < q; h++)
			println(ans[h] + query(ii[h], jj[h]));
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStream;

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

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            final int BUCKET = 500;

            int[] from = new int[m];
            int[] to = new int[m];
            int[] nextEdge = new int[m];

            int[] colorFirstEdge = new int[m];
            int[] colorDeg = new int[m];
            Arrays.fill(colorFirstEdge, -1);

            for (int i = 0; i < m; ++i) {
                int x = in.nextInt() - 1, y = in.nextInt() - 1, c = in.nextInt() - 1;
                from[i] = x;
                to[i] = y;
                nextEdge[i] = colorFirstEdge[c];
                colorFirstEdge[c] = i;
                colorDeg[c]++;
            }

            int q = in.nextInt();
            int[] x = new int[q];
            int[] y = new int[q];
            int[] answer = new int[q];
            for (int i = 0; i < q; ++i) {
                x[i] = in.nextInt() - 1;
                y[i] = in.nextInt() - 1;
                if (x[i] > y[i]) {
                    int aux = x[i];
                    x[i] = y[i];
                    y[i] = aux;
                }
            }

            Map<Pairii, Integer> compAdd = new HashMap<>();

            int[] father = new int[n];
            boolean[] used = new boolean[n];
            int[] nodes = new int[n];
            for (int c = 0; c < m; ++c) {
                if (colorDeg[c] > BUCKET) {
                    for (int e = colorFirstEdge[c]; e != -1; e = nextEdge[e]) {
                        union(father, from[e], to[e]);
                    }
                    for (int i = 0; i < q; ++i) {
                        if (find(father, x[i]) == find(father, y[i])) {
                            answer[i]++;
                        }
                    }
                    for (int e = colorFirstEdge[c]; e != -1; e = nextEdge[e]) {
                        father[from[e]] = 0;
                        father[to[e]] = 0;
                    }
                } else {
                    int pos = 0;
                    for (int e = colorFirstEdge[c]; e != -1; e = nextEdge[e]) {
                        union(father, from[e], to[e]);
                        if (!used[from[e]]) {
                            nodes[pos++] = from[e];
                            used[from[e]] = true;
                        }
                        if (!used[to[e]]) {
                            nodes[pos++] = to[e];
                            used[to[e]] = true;
                        }
                    }
                    for (int i = 0; i < pos; ++i) {
                        int n1 = nodes[i];
                        for (int j = 0; j < i; ++j) {
                            int n2 = nodes[j];
                            if (find(father, n1) == find(father, n2)) {
                                if (n1 < n2) {
                                    add(compAdd, new Pairii(n1, n2));
                                } else {
                                    add(compAdd, new Pairii(n2, n1));
                                }
                            }
                        }
                    }
                    for (int e = colorFirstEdge[c]; e != -1; e = nextEdge[e]) {
                        father[from[e]] = 0;
                        father[to[e]] = 0;
                        used[from[e]] = false;
                        used[to[e]] = false;
                    }
                }
            }

            for (int i = 0; i < q; ++i) {
                answer[i] += get(compAdd, new Pairii(x[i], y[i]));
                out.println(answer[i]);
            }
        }

        int find(int[] father, int x) {
            int y, p;
            for (y = x; father[y] != 0; y = father[y]) ;
            for (; x != y; x = p) {
                p = father[x];
                father[x] = y;
            }
            return y;
        }

        void union(int[] father, int x, int y) {
            x = find(father, x);
            y = find(father, y);
            if (x == y) return;
            father[x] = y;
        }

        void add(Map<Pairii, Integer> m, Pairii e) {
            m.put(e, get(m, e) + 1);
        }

        int get(Map<Pairii, Integer> m, Pairii e) {
            Integer p = m.get(e);
            return p == null ? 0 : p;
        }

    }

    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;
        }

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

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

        public String next() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuffer res = new StringBuffer();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

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

    }

    static class Pairii implements Comparable<Pairii> {
        public int first;
        public int second;

        public Pairii() {
        }

        public Pairii(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public int compareTo(Pairii other) {
            if (first != other.first) return first < other.first ? -1 : 1;
            if (second != other.second) return second < other.second ? -1 : 1;
            return 0;
        }

        public boolean equals(Object other) {
            if (!(other instanceof Pairii)) return false;
            return compareTo((Pairii) other) == 0;
        }

        public int hashCode() {
            return first * 31 + second;
        }

    }
}


import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.io.InputStream;
import java.util.HashMap;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;

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

class TaskD {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int N = in.nextInt(), M = in.nextInt();

        HashMap<Integer, Integer>[] pos = new HashMap[M];
        for (int i = 0; i < M; ++i) pos[i] = new HashMap<>();

        ArrayList<Pairii>[] edges = new ArrayList[M];
        for (int i = 0; i < M; ++i) edges[i] = new ArrayList<>();

        HashSet<Integer>[] colors = new HashSet[N];
        for (int i = 0; i < N; ++i) colors[i] = new HashSet<>();

        for (int i = 0; i < M; ++i) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1, c = in.nextInt() - 1;
            colors[x].add(c);
            colors[y].add(c);

            if (!pos[c].containsKey(x)) pos[c].put(x, pos[c].size());
            if (!pos[c].containsKey(y)) pos[c].put(y, pos[c].size());
            x = pos[c].get(x);
            y = pos[c].get(y);
            if (x > y) {
                int aux = x;
                x = y;
                y = aux;
            }
            edges[c].add(new Pairii(x, y));
        }

        int[][] father = new int[M][];
        for (int i = 0; i < M; ++i) {
            father[i] = new int[pos[i].size()];
            for (Pairii curr : edges[i])
                union(father[i], curr.first, curr.second);
        }

        HashMap<Pairii, Integer> answers = new HashMap<>();
        int Q = in.nextInt();
        while (Q-- > 0) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1;
            if (x > y) {
                int aux = x;
                x = y;
                y = aux;
            }

            if (answers.containsKey(new Pairii(x, y))) {
                out.println(answers.get(new Pairii(x, y)));
                continue;
            }

            if (colors[x].size() > colors[y].size()) {
                int aux = x;
                x = y;
                y = aux;
            }

            int ans = 0;
            for (int col: colors[x]) {
                if (!pos[col].containsKey(y)) continue;
                int xx = pos[col].get(x), yy = pos[col].get(y);
                if (find(father[col], xx) == find(father[col], yy)) ++ans;
            }

            out.println(ans);

            if (x > y) {
                int aux = x;
                x = y;
                y = aux;
            }
            answers.put(new Pairii(x, y), ans);
        }
    }

    int find(int[] father, int x) {
        int y, p;
        for (y = x; father[y] != 0; y = father[y]);
        for (; x != y; x = p) {
            p = father[x];
            father[x] = y;
        }
        return y;
    }

    void union(int[] father, int x, int y) {
        x = find(father, x);
        y = find(father, y);
        if (x == y) return;
        father[x] = y;
    }
}

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

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

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

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

    public String next() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));

        return res.toString();
    }

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

}

class Pairii implements Comparable<Pairii> {
    public int first, second;

    public Pairii(int first, int second) {
        this.first = first;
        this.second = second;
    }

    public int compareTo(Pairii other) {
        if (first != other.first) return first < other.first ? -1: 1;
        if (second != other.second) return second < other.second ? -1: 1;
        return 0;
    }

    public boolean equals(Object other) {
        if (!(other instanceof Pairii)) return false;
        return compareTo((Pairii) other) == 0;
    }

    public int hashCode() {
        return first * 31 + second;
    }
}


import java.util.TreeSet;
import java.util.TreeMap;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;

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

class TaskD {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int N = in.nextInt(), M = in.nextInt();

        TreeMap<Integer, Integer>[] pos = new TreeMap[M];
        for (int i = 0; i < M; ++i) pos[i] = new TreeMap<>();

        ArrayList<Pairii>[] edges = new ArrayList[M];
        for (int i = 0; i < M; ++i) edges[i] = new ArrayList<>();

        TreeSet<Integer>[] colors = new TreeSet[N];
        for (int i = 0; i < N; ++i) colors[i] = new TreeSet<>();

        for (int i = 0; i < M; ++i) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1, c = in.nextInt() - 1;
            colors[x].add(c);
            colors[y].add(c);

            if (!pos[c].containsKey(x)) pos[c].put(x, pos[c].size());
            if (!pos[c].containsKey(y)) pos[c].put(y, pos[c].size());
            x = pos[c].get(x);
            y = pos[c].get(y);
            edges[c].add(new Pairii(x, y));
        }

        int[][] father = new int[M][];
        for (int i = 0; i < M; ++i) {
            father[i] = new int[pos[i].size()];
            for (Pairii curr : edges[i])
                union(father[i], curr.first, curr.second);
        }

        TreeMap<Pairii, Integer> answers = new TreeMap<>();
        int Q = in.nextInt();
        while (Q-- > 0) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1;
            if (x > y) {
                int aux = x;
                x = y;
                y = aux;
            }

            if (answers.containsKey(new Pairii(x, y))) {
                out.println(answers.get(new Pairii(x, y)));
                continue;
            }

            if (colors[x].size() > colors[y].size()) {
                int aux = x;
                x = y;
                y = aux;
            }

            int ans = 0;
            for (int col: colors[x]) {
                if (!pos[col].containsKey(y)) continue;
                int xx = pos[col].get(x), yy = pos[col].get(y);
                if (find(father[col], xx) == find(father[col], yy)) ++ans;
            }

            out.println(ans);

            if (x > y) {
                int aux = x;
                x = y;
                y = aux;
            }
            answers.put(new Pairii(x, y), ans);
        }
    }

    int find(int[] father, int x) {
        int y, p;
        for (y = x; father[y] != 0; y = father[y]);
        for (; x != y; x = p) {
            p = father[x];
            father[x] = y;
        }
        return y;
    }

    void union(int[] father, int x, int y) {
        x = find(father, x);
        y = find(father, y);
        if (x == y) return;
        father[x] = y;
    }
}

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

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

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

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

    public String next() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));

        return res.toString();
    }

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

}

class Pairii implements Comparable<Pairii> {
    public int first, second;

    public Pairii(int first, int second) {
        this.first = first;
        this.second = second;
    }

    public int compareTo(Pairii other) {
        if (first != other.first) return first < other.first ? -1: 1;
        if (second != other.second) return second < other.second ? -1: 1;
        return 0;
    }

    public boolean equals(Object other) {
        if (!(other instanceof Pairii)) return false;
        return compareTo((Pairii) other) == 0;
    }

    public int hashCode() {
        return first * 31 + second;
    }
}


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

public class D {
	void run() {
		int n = in.nextInt();
		int T = 300;
		int m = in.nextInt();
		int[] a = new int[m];
		int[] b = new int[m];
		int[] c = new int[m];
		ArrayList<Integer>[] byColor = new ArrayList[m];
		for (int i = 0; i < m; i++) {
			byColor[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < m; i++) {
			a[i] = in.nextInt() - 1;
			b[i] = in.nextInt() - 1;
			c[i] = in.nextInt() - 1;
			byColor[c[i]].add(i);
		}
		ArrayList<Integer> popular = new ArrayList<Integer>();
		nei = new ArrayList[n];
		ArrayList<Integer>[] popColor = new ArrayList[n];
		Map<Long, Integer> count = new TreeMap<Long, Integer>();
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
			popColor[i] = new ArrayList<Integer>();
		}
		comp = new int[n];
		Arrays.fill(comp, -1);
		for (int k = 0; k < m; k++) {
			if (byColor[k].size() < T) {
				TreeSet<Integer> actual = new TreeSet<Integer>();
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
					actual.add(a[i]);
					actual.add(b[i]);
				}
				comps = 0;
				for (int i : actual) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i : actual) {
					for (int j : actual) {
						if (i >= j || comp[i] != comp[j]) {
							continue;
						}
						long enc = encode(i, j);
						count.put(enc, count.getOrDefault(enc, 0) + 1);
					}
				}
				for (int i : actual) {
					nei[i].clear();
					comp[i] = -1;
				}
			} else {
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
				}
				popular.add(k);
				comps = 0;
				for (int i = 0; i < n; i++) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i = 0; i < n; i++) {
					popColor[i].add(comp[i]);
				}
				for (int i = 0; i < n; i++) {
					nei[i].clear();
				}
				Arrays.fill(comp, -1);
			}
		}
		int queries = in.nextInt();
		for (int q = 0; q < queries; q++) {
			int x = in.nextInt() - 1;
			int y = in.nextInt() - 1;
			if (x >= y) {
				int t = x; x = y; y = t;
			}
			long enc = encode(x, y);
			int res = count.getOrDefault(enc, 0);
			List<Integer> cx = popColor[x];
			List<Integer> cy = popColor[y];
			for (int i = 0; i < cx.size(); i++) {
				if (cx.get(i).equals(cy.get(i))) {
					res++;
				}
			}
			out.println(res);
		}
	}

	long encode(int a, int b) {
		return b | ((long) a << 32);
	}

	ArrayList<Integer>[] nei;
	int[] comp;
	int comps;

	void dfs(int v) {
		comp[v] = comps;
		for (int u : nei[v]) {
			if (comp[u] >= 0) {
				continue;
			}
			dfs(u);
		}
	}

	static boolean stdStreams = true;
	static String fileName = D.class.getSimpleName().replaceFirst("_.*", "").toLowerCase();
	static String inputFileName = fileName + ".in";
	static String outputFileName = fileName + ".out";
	static MyScanner in;
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Locale.setDefault(Locale.US);
		BufferedReader br;
		if (stdStreams) {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
		} else {
			br = new BufferedReader(new FileReader(inputFileName));
			out = new PrintWriter(outputFileName);
		}
		in = new MyScanner(br);
		int tests = 1;//in.nextInt();
		for (int test = 0; test < tests; test++) {
			new D().run();
		}
		br.close();
		out.close();
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		MyScanner(BufferedReader br) {
			this.br = br;
		}

		void findToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}

		String next() {
			findToken();
			return st.nextToken();
		}

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

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

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


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

public class D {
	@SuppressWarnings("unchecked")
	void run() {
		int n = in.nextInt();
		int T = 200;
		int m = in.nextInt();
		int[] a = new int[m];
		int[] b = new int[m];
		int[] c = new int[m];
		ArrayList<Integer>[] byColor = new ArrayList[m];
		for (int i = 0; i < m; i++) {
			byColor[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < m; i++) {
			a[i] = in.nextInt() - 1;
			b[i] = in.nextInt() - 1;
			c[i] = in.nextInt() - 1;
			byColor[c[i]].add(i);
		}
		int queries = in.nextInt();
		int popular = 0;
		nei = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
		}
		comp = new int[n];
		Arrays.fill(comp, -1);
		for (int k = 0; k < m; k++) {
			if (byColor[k].size() >= T) {
				popular++;
			}
		}
		int[][] popColor = new int[n][popular];
		Map<Long, Integer> count = new TreeMap<Long, Integer>();
		for (int k = 0, p = 0; k < m; k++) {
			if (byColor[k].size() < T) {
				TreeSet<Integer> actual = new TreeSet<Integer>();
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
					actual.add(a[i]);
					actual.add(b[i]);
				}
				comps = 0;
				for (int i : actual) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i : actual) {
					for (int j : actual) {
						if (i >= j || comp[i] != comp[j]) {
							continue;
						}
						long enc = encode(i, j);
						count.put(enc, count.getOrDefault(enc, 0) + 1);
					}
				}
				for (int i : actual) {
					nei[i].clear();
					comp[i] = -1;
				}
			} else {
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
				}
				comps = 0;
				for (int i = 0; i < n; i++) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i = 0; i < n; i++) {
					popColor[i][p] = comp[i];
				}
				for (int i = 0; i < n; i++) {
					nei[i].clear();
				}
				Arrays.fill(comp, -1);
				p++;
			}
		}
		for (int q = 0; q < queries; q++) {
			int x = in.nextInt() - 1;
			int y = in.nextInt() - 1;
			if (x >= y) {
				int t = x; x = y; y = t;
			}
			long enc = encode(x, y);
			int res = count.getOrDefault(enc, 0);
			int[] cx = popColor[x];
			int[] cy = popColor[y];
			for (int i = 0; i < popular; i++) {
				if (cx[i] == cy[i]) {
					res++;
				}
			}
			out.println(res);
		}
	}

	long encode(int a, int b) {
		return b | ((long) a << 32);
	}

	ArrayList<Integer>[] nei;
	int[] comp;
	int comps;

	void dfs(int v) {
		comp[v] = comps;
		for (int u : nei[v]) {
			if (comp[u] >= 0) {
				continue;
			}
			dfs(u);
		}
	}

	static boolean stdStreams = true;
	static String fileName = D.class.getSimpleName().replaceFirst("_.*", "").toLowerCase();
	static String inputFileName = fileName + ".in";
	static String outputFileName = fileName + ".out";
	static MyScanner in;
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Locale.setDefault(Locale.US);
		BufferedReader br;
		if (stdStreams) {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
		} else {
			br = new BufferedReader(new FileReader(inputFileName));
			out = new PrintWriter(outputFileName);
		}
		in = new MyScanner(br);
		int tests = 1;//in.nextInt();
		for (int test = 0; test < tests; test++) {
			new D().run();
		}
		br.close();
		out.close();
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		MyScanner(BufferedReader br) {
			this.br = br;
		}

		void findToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}

		String next() {
			findToken();
			return st.nextToken();
		}

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

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

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


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

public class D {
	@SuppressWarnings("unchecked")
	void run() {
		int n = in.nextInt();
		int T = 300;
		int m = in.nextInt();
		int[] a = new int[m];
		int[] b = new int[m];
		int[] c = new int[m];
		ArrayList<Integer>[] byColor = new ArrayList[m];
		for (int i = 0; i < m; i++) {
			byColor[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < m; i++) {
			a[i] = in.nextInt() - 1;
			b[i] = in.nextInt() - 1;
			c[i] = in.nextInt() - 1;
			byColor[c[i]].add(i);
		}
		int queries = in.nextInt();
		int popular = 0;
		nei = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
		}
		comp = new int[n];
		Arrays.fill(comp, -1);
		for (int k = 0; k < m; k++) {
			if (byColor[k].size() >= T) {
				popular++;
			}
		}
		int[][] popColor = new int[n][popular];
		Map<Long, Integer> count = new TreeMap<Long, Integer>();
		for (int k = 0, p = 0; k < m; k++) {
			if (byColor[k].size() < T) {
				TreeSet<Integer> actual = new TreeSet<Integer>();
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
					actual.add(a[i]);
					actual.add(b[i]);
				}
				comps = 0;
				for (int i : actual) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i : actual) {
					for (int j : actual) {
						if (i >= j || comp[i] != comp[j]) {
							continue;
						}
						long enc = encode(i, j);
						count.put(enc, count.getOrDefault(enc, 0) + 1);
					}
				}
				for (int i : actual) {
					nei[i].clear();
					comp[i] = -1;
				}
			} else {
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
				}
				comps = 0;
				for (int i = 0; i < n; i++) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i = 0; i < n; i++) {
					popColor[i][p] = comp[i];
				}
				for (int i = 0; i < n; i++) {
					nei[i].clear();
				}
				Arrays.fill(comp, -1);
				p++;
			}
		}
		for (int q = 0; q < queries; q++) {
			int x = in.nextInt() - 1;
			int y = in.nextInt() - 1;
			if (x >= y) {
				int t = x; x = y; y = t;
			}
			long enc = encode(x, y);
			int res = count.get(enc);
			int[] cx = popColor[x];
			int[] cy = popColor[y];
			for (int i = 0; i < popular; i++) {
				if (cx[i] == cy[i]) {
					res++;
				}
			}
			out.println(res);
		}
	}

	long encode(int a, int b) {
		return b | ((long) a << 32);
	}

	ArrayList<Integer>[] nei;
	int[] comp;
	int comps;

	void dfs(int v) {
		comp[v] = comps;
		for (int u : nei[v]) {
			if (comp[u] >= 0) {
				continue;
			}
			dfs(u);
		}
	}

	static boolean stdStreams = true;
	static String fileName = D.class.getSimpleName().replaceFirst("_.*", "").toLowerCase();
	static String inputFileName = fileName + ".in";
	static String outputFileName = fileName + ".out";
	static MyScanner in;
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Locale.setDefault(Locale.US);
		BufferedReader br;
		if (stdStreams) {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
		} else {
			br = new BufferedReader(new FileReader(inputFileName));
			out = new PrintWriter(outputFileName);
		}
		in = new MyScanner(br);
		int tests = 1;//in.nextInt();
		for (int test = 0; test < tests; test++) {
			new D().run();
		}
		br.close();
		out.close();
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		MyScanner(BufferedReader br) {
			this.br = br;
		}

		void findToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}

		String next() {
			findToken();
			return st.nextToken();
		}

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

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

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


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

public class D_ok {
	@SuppressWarnings("unchecked")
	void run() {
		int n = in.nextInt();
		int T = 300;
		int m = in.nextInt();
		int[] a = new int[m];
		int[] b = new int[m];
		int[] c = new int[m];
		ArrayList<Integer>[] byColor = new ArrayList[m];
		for (int i = 0; i < m; i++) {
			byColor[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < m; i++) {
			a[i] = in.nextInt() - 1;
			b[i] = in.nextInt() - 1;
			c[i] = in.nextInt() - 1;
			byColor[c[i]].add(i);
		}
		int queries = in.nextInt();
		int[] x = new int[queries];
		int[] y = new int[queries];
		Map<Long, Integer> count = new TreeMap<Long, Integer>();
		for (int q = 0; q < queries; q++) {
			x[q] = in.nextInt() - 1;
			y[q] = in.nextInt() - 1;
			if (x[q] >= y[q]) {
				int t = x[q]; x[q] = y[q]; y[q] = t;
			}
			long enc = encode(x[q], y[q]);
			count.put(enc, 0);
		}
		int popular = 0;
		nei = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
		}
		comp = new int[n];
		Arrays.fill(comp, -1);
		for (int k = 0; k < m; k++) {
			if (byColor[k].size() >= T) {
				popular++;
			}
		}
		int[][] popColor = new int[n][popular];
		for (int k = 0, p = 0; k < m; k++) {
			if (byColor[k].size() < T) {
				TreeSet<Integer> actual = new TreeSet<Integer>();
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
					actual.add(a[i]);
					actual.add(b[i]);
				}
				comps = 0;
				for (int i : actual) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i : actual) {
					for (int j : actual) {
						if (i >= j || comp[i] != comp[j]) {
							continue;
						}
						long enc = encode(i, j);
						if (!count.containsKey(enc)) {
							continue;
						}
						count.put(enc, count.get(enc) + 1);
					}
				}
				for (int i : actual) {
					nei[i].clear();
					comp[i] = -1;
				}
			} else {
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
				}
				comps = 0;
				for (int i = 0; i < n; i++) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i = 0; i < n; i++) {
					popColor[i][p] = comp[i];
				}
				for (int i = 0; i < n; i++) {
					nei[i].clear();
				}
				Arrays.fill(comp, -1);
				p++;
			}
		}
		for (int q = 0; q < queries; q++) {
			long enc = encode(x[q], y[q]);
			int res = count.get(enc);
			int[] cx = popColor[x[q]];
			int[] cy = popColor[y[q]];
			for (int i = 0; i < popular; i++) {
				if (cx[i] == cy[i]) {
					res++;
				}
			}
			out.println(res);
		}
	}

	long encode(int a, int b) {
		return b | ((long) a << 32);
	}

	ArrayList<Integer>[] nei;
	int[] comp;
	int comps;

	void dfs(int v) {
		comp[v] = comps;
		for (int u : nei[v]) {
			if (comp[u] >= 0) {
				continue;
			}
			dfs(u);
		}
	}

	static boolean stdStreams = true;
	static String fileName = D_ok.class.getSimpleName().replaceFirst("_.*", "").toLowerCase();
	static String inputFileName = fileName + ".in";
	static String outputFileName = fileName + ".out";
	static MyScanner in;
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Locale.setDefault(Locale.US);
		BufferedReader br;
		if (stdStreams) {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
		} else {
			br = new BufferedReader(new FileReader(inputFileName));
			out = new PrintWriter(outputFileName);
		}
		in = new MyScanner(br);
		int tests = 1;//in.nextInt();
		for (int test = 0; test < tests; test++) {
			new D_ok().run();
		}
		br.close();
		out.close();
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		MyScanner(BufferedReader br) {
			this.br = br;
		}

		void findToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}

		String next() {
			findToken();
			return st.nextToken();
		}

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

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

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


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

public class D {
	@SuppressWarnings("unchecked")
	void run() {
		int n = in.nextInt();
		int T = 300;
		int m = in.nextInt();
		int[] a = new int[m];
		int[] b = new int[m];
		int[] c = new int[m];
		ArrayList<Integer>[] byColor = new ArrayList[m];
		for (int i = 0; i < m; i++) {
			byColor[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < m; i++) {
			a[i] = in.nextInt() - 1;
			b[i] = in.nextInt() - 1;
			c[i] = in.nextInt() - 1;
			byColor[c[i]].add(i);
		}
		int queries = in.nextInt();
		int popular = 0;
		nei = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
		}
		comp = new int[n];
		Arrays.fill(comp, -1);
		for (int k = 0; k < m; k++) {
			if (byColor[k].size() >= T) {
				popular++;
			}
		}
		int[][] popColor = new int[n][popular];
		Map<Long, Integer> count = new TreeMap<Long, Integer>();
		for (int k = 0, p = 0; k < m; k++) {
			if (byColor[k].size() < T) {
				TreeSet<Integer> actual = new TreeSet<Integer>();
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
					actual.add(a[i]);
					actual.add(b[i]);
				}
				comps = 0;
				for (int i : actual) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i : actual) {
					for (int j : actual) {
						if (i >= j || comp[i] != comp[j]) {
							continue;
						}
						long enc = encode(i, j);
						count.put(enc, count.getOrDefault(enc, 0) + 1);
					}
				}
				for (int i : actual) {
					nei[i].clear();
					comp[i] = -1;
				}
			} else {
				for (int i : byColor[k]) {
					nei[a[i]].add(b[i]);
					nei[b[i]].add(a[i]);
				}
				comps = 0;
				for (int i = 0; i < n; i++) {
					if (comp[i] >= 0) {
						continue;
					}
					dfs(i);
					comps++;
				}
				for (int i = 0; i < n; i++) {
					popColor[i][p] = comp[i];
				}
				for (int i = 0; i < n; i++) {
					nei[i].clear();
				}
				Arrays.fill(comp, -1);
				p++;
			}
		}
		for (int q = 0; q < queries; q++) {
			int x = in.nextInt() - 1;
			int y = in.nextInt() - 1;
			if (x >= y) {
				int t = x; x = y; y = t;
			}
			long enc = encode(x, y);
			int res = count.getOrDefault(enc, 0);
			int[] cx = popColor[x];
			int[] cy = popColor[y];
			for (int i = 0; i < popular; i++) {
				if (cx[i] == cy[i]) {
					res++;
				}
			}
			out.println(res);
		}
	}

	long encode(int a, int b) {
		return b | ((long) a << 32);
	}

	ArrayList<Integer>[] nei;
	int[] comp;
	int comps;

	void dfs(int v) {
		comp[v] = comps;
		for (int u : nei[v]) {
			if (comp[u] >= 0) {
				continue;
			}
			dfs(u);
		}
	}

	static boolean stdStreams = true;
	static String fileName = D.class.getSimpleName().replaceFirst("_.*", "").toLowerCase();
	static String inputFileName = fileName + ".in";
	static String outputFileName = fileName + ".out";
	static MyScanner in;
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Locale.setDefault(Locale.US);
		BufferedReader br;
		if (stdStreams) {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
		} else {
			br = new BufferedReader(new FileReader(inputFileName));
			out = new PrintWriter(outputFileName);
		}
		in = new MyScanner(br);
		int tests = 1;//in.nextInt();
		for (int test = 0; test < tests; test++) {
			new D().run();
		}
		br.close();
		out.close();
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		MyScanner(BufferedReader br) {
			this.br = br;
		}

		void findToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}

		String next() {
			findToken();
			return st.nextToken();
		}

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

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

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


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

public class Main{
	static int[][] p, rank;
	static void dsu(int c,int n) {
		p[c] = new int[n];
		rank[c] = new int[n];
		for (int i = 0; i < n; i++) {  p[c][i] = i; }
	}
	static int findSet(int c,int i) { return p[c][i] == i ? i : (p[c][i] = findSet(c,p[c][i])); }

	static boolean isSameSet(int c,int i, int j) { return findSet(c,i) == findSet(c,j); }

	static void unionSet(int c,int i, int j) {
		if (isSameSet(c,i, j))
			return;
		int x = findSet(c,i), y = findSet(c,j);
		if(rank[c][x] > rank[c][y]) { p[c][y] = x;}
		else
		{	p[c][x] = y;
			if(rank[c][x] == rank[c][y]) rank[c][y]++;
		}
	}
	static void main() throws Exception{
		int n=sc.nextInt(),m=sc.nextInt();
		int[][]edges=new int[m][3];
		HashMap<Integer, Integer>[]maps=new HashMap[m];
		for(int i=0;i<m;i++) {
			edges[i]=new int[] {sc.nextInt()-1,sc.nextInt()-1,sc.nextInt()-1};
			maps[i]=new HashMap<Integer, Integer>();
		}
		for(int i=0;i<m;i++) {
			int x=edges[i][0],y=edges[i][1],c=edges[i][2];
			if(!maps[c].containsKey(x)) {
				maps[c].put(x, maps[c].size());
			}
			if(!maps[c].containsKey(y)) {
				maps[c].put(y, maps[c].size());
			}
		}
		p=new int[m][];
		rank=new int[m][];
		for(int i=0;i<m;i++) {
			if(maps[i].size()>0) {
				dsu(i, maps[i].size());
			}
		}
		HashSet<Integer>[]colHs=new HashSet[n];
		ArrayList<Integer>[]colAl=new ArrayList[n];
		for(int i=0;i<n;i++) {
			colHs[i]=new HashSet<Integer>();
			colAl[i]=new ArrayList<Integer>();
		}
		for(int i=0;i<m;i++) {
			int x=edges[i][0],y=edges[i][1],c=edges[i][2];
			unionSet(c,maps[c].get(x), maps[c].get(y));
			if(!colHs[x].contains(c)) {
				colHs[x].add(c);
				colAl[x].add(c);
			}
			if(!colHs[y].contains(c)) {
				colHs[y].add(c);
				colAl[y].add(c);
			}
		}
		HashMap<Long, Integer>memo=new HashMap<Long, Integer>();
		int q=sc.nextInt();
		for(int i=0;i<q;i++) {
			int u=sc.nextInt()-1,v=sc.nextInt()-1;
			long curHash=Math.min(u, v)*1l*n+Math.max(u, v);
			if(memo.containsKey(curHash)) {
				pw.println(memo.get(curHash));
				continue;
			}
			int ans=0;
			if(colAl[u].size()>colAl[v].size()) {
				int tmp=u;
				u=v;
				v=tmp;
			}
			for(int j=0;j<colAl[u].size();j++) {
				int c=colAl[u].get(j);
				if(maps[c].containsKey(v) && isSameSet(c,maps[c].get(u), maps[c].get(v))) {
					ans++;
				}
			}
			pw.println(ans);
			memo.put(curHash, ans);
		}
	}
	public static void main(String[] args) throws Exception {
		sc = new MScanner(System.in);
		pw = new PrintWriter(System.out);
//		int tc = 1;
//		tc=sc.nextInt();
//		while (tc-- > 0)
			main();
		pw.flush();
	}

	static PrintWriter pw;
	static MScanner sc;

	static class MScanner {
		StringTokenizer st;
		BufferedReader br;

		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

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

		public int[] intArr(int n) throws IOException {
			int[] in = new int[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			return in;
		}

		public long[] longArr(int n) throws IOException {
			long[] in = new long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			return in;
		}

		public int[] intSortedArr(int n) throws IOException {
			int[] in = new int[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			shuffle(in);
			Arrays.sort(in);
			return in;
		}

		public long[] longSortedArr(int n) throws IOException {
			long[] in = new long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			shuffle(in);
			Arrays.sort(in);
			return in;
		}

		public Integer[] IntegerArr(int n) throws IOException {
			Integer[] in = new Integer[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			return in;
		}

		public Long[] LongArr(int n) throws IOException {
			Long[] in = new Long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			return in;
		}

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

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

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

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

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}

	static void shuffle(int[] in) {
		for (int i = 0; i < in.length; i++) {
			int idx = (int) (Math.random() * (i + 1));
			int tmp = in[i];
			in[i] = in[idx];
			in[idx] = tmp;
		}
	}

	static void shuffle(long[] in) {
		for (int i = 0; i < in.length; i++) {
			int idx = (int) (Math.random() * (i + 1));
			long tmp = in[i];
			in[i] = in[idx];
			in[idx] = tmp;
		}
	}
}


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

public class Main{
	static int[][] p, rank;
	static void dsu(int c,int n) {
		p[c] = new int[n];
		rank[c] = new int[n];
		for (int i = 0; i < n; i++) {  p[c][i] = i; }
	}
	public static int findSet(int c,int i) { return p[c][i] == i ? i : (p[c][i] = findSet(c,p[c][i])); }

	public static boolean isSameSet(int c,int i, int j) { return findSet(c,i) == findSet(c,j); }

	public static boolean unionSet(int c,int i, int j)
	{
		if (isSameSet(c,i, j))
			return false;
		int x = findSet(c,i), y = findSet(c,j);
		if(rank[c][x] > rank[c][y]) { p[c][y] = x;}
		else
		{	p[c][x] = y;
			if(rank[c][x] == rank[c][y]) rank[c][y]++;
		}
		return true;
	}
	static void main() throws Exception{
		int n=sc.nextInt(),m=sc.nextInt();
		int[][]edges=new int[m][3];
		HashMap<Integer, Integer>[]maps=new HashMap[m];
		for(int i=0;i<m;i++) {
			edges[i]=new int[] {sc.nextInt()-1,sc.nextInt()-1,sc.nextInt()-1};
			maps[i]=new HashMap<Integer, Integer>();
		}
		for(int i=0;i<m;i++) {
			int x=edges[i][0],y=edges[i][1],c=edges[i][2];
			if(!maps[c].containsKey(x)) {
				maps[c].put(x, maps[c].size());
			}
			if(!maps[c].containsKey(y)) {
				maps[c].put(y, maps[c].size());
			}
		}
		p=new int[m][];
		rank=new int[m][];
		for(int i=0;i<m;i++) {
			if(maps[i].size()>0) {
				dsu(i, maps[i].size());
			}
		}
		HashSet<Integer>[]colHs=new HashSet[n];
		ArrayList<Integer>[]colAl=new ArrayList[n];
		for(int i=0;i<n;i++) {
			colHs[i]=new HashSet<Integer>();
			colAl[i]=new ArrayList<Integer>();
		}
		for(int i=0;i<m;i++) {
			int x=edges[i][0],y=edges[i][1],c=edges[i][2];
			unionSet(c,maps[c].get(x), maps[c].get(y));
			if(!colHs[x].contains(c)) {
				colHs[x].add(c);
				colAl[x].add(c);
			}
			if(!colHs[y].contains(c)) {
				colHs[y].add(c);
				colAl[y].add(c);
			}
		}
		HashMap<Long, Integer>memo=new HashMap<Long, Integer>();
		int q=sc.nextInt();
		for(int i=0;i<q;i++) {
			int u=sc.nextInt()-1,v=sc.nextInt()-1;
			long curHash=Math.min(u, v)*1l*n+Math.max(u, v);
			if(memo.containsKey(curHash)) {
				pw.println(memo.get(curHash));
				continue;
			}
			int ans=0;
			if(colAl[u].size()>colAl[v].size()) {
				int tmp=u;
				u=v;
				v=tmp;
			}
			for(int j=0;j<colAl[u].size();j++) {
				int c=colAl[u].get(j);
				if(maps[c].containsKey(u) && maps[c].containsKey(v) && isSameSet(c,maps[c].get(u), maps[c].get(v))) {
					ans++;
				}
			}
			pw.println(ans);
			memo.put(curHash, ans);
		}
	}
	public static void main(String[] args) throws Exception {
		sc = new MScanner(System.in);
		pw = new PrintWriter(System.out);
		int tc = 1;
//		tc=sc.nextInt();
		while (tc-- > 0)
			main();
		pw.flush();
	}

	static PrintWriter pw;
	static MScanner sc;

	static class MScanner {
		StringTokenizer st;
		BufferedReader br;

		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

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

		public int[] intArr(int n) throws IOException {
			int[] in = new int[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			return in;
		}

		public long[] longArr(int n) throws IOException {
			long[] in = new long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			return in;
		}

		public int[] intSortedArr(int n) throws IOException {
			int[] in = new int[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			shuffle(in);
			Arrays.sort(in);
			return in;
		}

		public long[] longSortedArr(int n) throws IOException {
			long[] in = new long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			shuffle(in);
			Arrays.sort(in);
			return in;
		}

		public Integer[] IntegerArr(int n) throws IOException {
			Integer[] in = new Integer[n];
			for (int i = 0; i < n; i++)
				in[i] = nextInt();
			return in;
		}

		public Long[] LongArr(int n) throws IOException {
			Long[] in = new Long[n];
			for (int i = 0; i < n; i++)
				in[i] = nextLong();
			return in;
		}

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

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

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

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

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}

	static void shuffle(int[] in) {
		for (int i = 0; i < in.length; i++) {
			int idx = (int) (Math.random() * (i + 1));
			int tmp = in[i];
			in[i] = in[idx];
			in[idx] = tmp;
		}
	}

	static void shuffle(long[] in) {
		for (int i = 0; i < in.length; i++) {
			int idx = (int) (Math.random() * (i + 1));
			long tmp = in[i];
			in[i] = in[idx];
			in[idx] = tmp;
		}
	}
}