#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 5;
struct segment_change {
  int to_add;
  segment_change(int _to_add = 0) : to_add(_to_add) {}
  void reset() { to_add = 0; }
  bool has_change() const { return to_add != 0; }
  segment_change combine(const segment_change &other) const {
    return segment_change(to_add + other.to_add);
  }
};
struct segment {
  int minimum, count_of_min;
  segment(int _minimum = INF, int _count_of_min = 0)
      : minimum(_minimum), count_of_min(_count_of_min) {}
  void apply(int, const segment_change &change) { minimum += change.to_add; }
  void join(const segment &other) {
    if (other.minimum < minimum)
      *this = other;
    else if (other.minimum == minimum)
      count_of_min += other.count_of_min;
  }
  void join(const segment &a, const segment &b) {
    *this = a;
    join(b);
  }
};
struct min_count_seg_tree {
  int tree_n = 0;
  vector<segment> tree;
  vector<segment_change> changes;
  min_count_seg_tree(int n = 0) {
    if (n > 0) init(n);
  }
  void init(int n) {
    tree_n = 1;
    while (tree_n < n) tree_n *= 2;
    tree.assign(2 * tree_n, segment());
    changes.assign(tree_n, segment_change());
  }
  void build(const vector<segment> &initial) {
    int n = initial.size();
    assert(n <= tree_n);
    for (int i = 0; i < n; i++) tree[tree_n + i] = initial[i];
    for (int position = tree_n - 1; position > 0; position--)
      tree[position].join(tree[2 * position], tree[2 * position + 1]);
  }
  void push_down(int position, int length) {
    if (!changes[position].has_change()) return;
    if (2 * position < tree_n) {
      changes[2 * position] = changes[2 * position].combine(changes[position]);
      changes[2 * position + 1] =
          changes[2 * position + 1].combine(changes[position]);
    }
    tree[2 * position].apply(length / 2, changes[position]);
    tree[2 * position + 1].apply(length / 2, changes[position]);
    changes[position].reset();
  }
  void push_all(int a, int b) {
    assert(0 <= a && a < b && b <= tree_n);
    a += tree_n;
    b += tree_n - 1;
    for (int up = 31 - __builtin_clz(tree_n); up > 0; up--) {
      int x = a >> up, y = b >> up;
      push_down(x, 1 << up);
      if (x != y) push_down(y, 1 << up);
    }
  }
  void join_and_apply(int position, int length) {
    tree[position].join(tree[2 * position], tree[2 * position + 1]);
    tree[position].apply(length, changes[position]);
  }
  void join_all(int a, int b) {
    assert(0 <= a && a < b && b <= tree_n);
    a += tree_n;
    b += tree_n - 1;
    int length = 1;
    while (a > 1) {
      a /= 2;
      b /= 2;
      length *= 2;
      join_and_apply(a, length);
      if (a != b) join_and_apply(b, length);
    }
  }
  pair<int, int> right_half[32];
  template <typename T_range_op>
  void process_range(int a, int b, bool needs_join, T_range_op &&range_op) {
    if (a == b) return;
    push_all(a, b);
    int original_a = a, original_b = b;
    int length = 1, r_size = 0;
    for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2, length *= 2) {
      if (a & 1) range_op(a++, length);
      if (b & 1) right_half[r_size++] = {--b, length};
    }
    for (int i = r_size - 1; i >= 0; i--)
      range_op(right_half[i].first, right_half[i].second);
    if (needs_join) join_all(original_a, original_b);
  }
  segment query(int a, int b) {
    assert(0 <= a && a <= b && b <= tree_n);
    segment answer;
    process_range(a, b, false,
                  [&](int position, int) { answer.join(tree[position]); });
    return answer;
  }
  void update(int a, int b, const segment_change &change) {
    assert(0 <= a && a <= b && b <= tree_n);
    process_range(a, b, true, [&](int position, int length) {
      tree[position].apply(length, change);
      if (position < tree_n)
        changes[position] = changes[position].combine(change);
    });
  }
};
int N, Q;
vector<vector<int>> adj;
vector<int> tour_start, tour_end;
void dfs(int node, int parent) {
  static int tour;
  if (parent < 0) tour = 0;
  tour_start[node] = tour++;
  if (parent >= 0)
    adj[node].erase(find(adj[node].begin(), adj[node].end(), parent));
  for (int neighbor : adj[node])
    if (neighbor != parent) dfs(neighbor, node);
  tour_end[node] = tour;
}
bool is_ancestor(int u, int v) {
  return tour_start[u] <= tour_start[v] && tour_start[v] < tour_end[u];
}
min_count_seg_tree tree;
int child_ancestor(int a, int b) {
  assert(a != b);
  assert(is_ancestor(a, b));
  assert(!adj[a].empty());
  int low = 0, high = (int)adj[a].size() - 1;
  while (low < high) {
    int mid = (low + high) / 2;
    if (tour_start[b] < tour_end[adj[a][mid]])
      high = mid;
    else
      low = mid + 1;
  }
  int child = adj[a][low];
  assert(is_ancestor(child, b));
  return child;
}
void update_back_edge(int u, int v, int direction) {
  int u_child = child_ancestor(u, v);
  tree.update(tour_start[u_child], tour_end[u_child],
              segment_change(direction));
  tree.update(tour_start[v], tour_end[v], segment_change(-direction));
}
void update_cross_edge(int u, int v, int direction) {
  tree.update(0, tree.tree_n, segment_change(direction));
  tree.update(tour_start[u], tour_end[u], segment_change(-direction));
  tree.update(tour_start[v], tour_end[v], segment_change(-direction));
}
void update(int u, int v, int direction) {
  if (is_ancestor(u, v))
    update_back_edge(u, v, direction);
  else if (is_ancestor(v, u))
    update_back_edge(v, u, direction);
  else
    update_cross_edge(u, v, direction);
}
int main() {
  scanf("%d %d", &N, &Q);
  adj.assign(N, {});
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  tour_start.resize(N);
  tour_end.resize(N);
  dfs(0, -1);
  tree.init(N);
  tree.build(vector<segment>(N, segment(0, 1)));
  set<pair<int, int>> contained;
  for (int q = 0; q < Q; q++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    if (u > v) swap(u, v);
    int direction = +1;
    if (!contained.insert({u, v}).second) {
      contained.erase({u, v});
      direction = -1;
    }
    update(u, v, direction);
    const segment &all = tree.query(0, tree.tree_n);
    printf("%d\n", all.minimum == 0 ? all.count_of_min : 0);
  }
}
