#include <bits/stdc++.h>
constexpr unsigned primes[]{2672090437, 2569161337, 2414657393};
constexpr int np = sizeof(primes) / sizeof(*primes);
std::vector<std::array<unsigned, np> > pow2;
void setpow2(int maxp) {
  pow2.resize(maxp + 1);
  for (int i = 0; i < np; i++) pow2[0][i] = 1;
  for (int i = 1; i <= maxp; i++)
    for (int j = 0; j < np; j++) pow2[i][j] = pow2[i - 1][j] * 2ULL % primes[j];
}
struct hash {
  unsigned m[np];
  int nbits;
  hash() {}
  hash(unsigned num, int nbits = 1) : nbits(nbits) {
    for (int i = 0; i < np; i++) m[i] = num;
  }
};
hash join(hash a, hash b) {
  hash out;
  out.nbits = a.nbits + b.nbits;
  for (int i = 0; i < np; i++)
    out.m[i] = (a.m[i] * (uint64_t)pow2[b.nbits][i] + b.m[i]) % primes[i];
  return out;
}
bool operator<(hash a, hash b) {
  if (a.nbits != b.nbits) return a.nbits < b.nbits;
  return memcmp(a.m, b.m, sizeof(a.m)) < 0;
}
int w[100000];
std::vector<int> adj[100000];
hash h0[100000];
hash hnew[100000];
int deg[100000];
int findw(int v, int par = -1) {
  int t = 1;
  for (int x : adj[v]) {
    if (x != par) t += findw(x, v);
  }
  return w[v] = t;
}
void genh0(int v, bool rec = true) {
  if (rec) {
    for (int x : adj[v]) genh0(x);
  }
  std::sort(adj[v].begin(), adj[v].end(),
            [](int a, int b) { return h0[a] < h0[b]; });
  hash out(0);
  for (int x : adj[v]) out = join(out, h0[x]);
  h0[v] = join(out, hash(1));
}
void hconcat(int v, hash h) {
  hnew[v] = memcmp(hnew[v].m, h.m, sizeof(h.m)) < 0 ? join(hnew[v], h)
                                                    : join(h, hnew[v]);
  for (int x : adj[v]) hconcat(x, h);
}
int main() {
  std::ios_base::sync_with_stdio(false);
  int n;
  scanf("%d", &n);
  setpow2(2 * n + 5);
  for (int i = n; --i;) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
    ++deg[a];
    ++deg[b];
  }
  findw(0);
  std::vector<int> center;
  for (int i = n; i--;) {
    if (n % 2 == 0 && w[i] == n / 2) {
      for (int j : adj[i]) {
        if (w[j] > w[i]) {
          center = {i, j};
          break;
        }
      }
      break;
    } else if (n - w[i] < (n + 1) / 2) {
      bool isC = true;
      for (int v : adj[i]) isC &= w[v] > w[i] || w[v] < (n + 1) / 2;
      if (isC) {
        center = {i};
        break;
      }
    }
  }
  bool ecent = center.size() == 2;
  for (auto i = center.size(); i--;) findw(center[i], center[i ^ +ecent]);
  for (int i = n; i--;) {
    std::sort(adj[i].begin(), adj[i].end(),
              [](int a, int b) { return w[a] < w[b]; });
    if (n > 1 && (ecent || i != center[0])) adj[i].pop_back();
  }
  struct split {
    const int *eqb, *eqe;
    hash pre, post;
  };
  std::vector<split> ss;
  const hash h01 = join(hash(0), hash(1));
  std::function<void(int, hash, hash, int)> genh;
  int nbad = 0;
  genh = [&](int v, hash pre, hash post, int skipw) {
    if (deg[v] < 4) {
      hash h = join(pre, h01);
      for (int x : adj[v]) h = join(h, h0[x]);
      h = join(h, post);
      for (auto it = ss.crbegin(); it != ss.crend(); ++it) {
        hash hh = it->pre;
        bool inserted = false;
        for (const int* i = it->eqb; i != it->eqe; ++i) {
          if (!inserted && memcmp(h.m, h0[*i].m, sizeof(h.m)) < 0) {
            inserted = true;
            hh = join(hh, h);
          }
          hh = join(hh, h0[*i]);
        }
        if (!inserted) hh = join(hh, h);
        h = join(hh, it->post);
      }
      hnew[v] = h;
    } else {
      hnew[v].nbits = -1;
      nbad++;
    }
    for (auto aj = adj[v].cbegin(), ae = adj[v].cend(); aj != ae; ++aj) {
      if (w[*aj] == skipw) continue;
      auto a2 = aj;
      do ++a2;
      while (a2 != ae && w[*a2] == w[*aj]);
      hash pre2 = pre, post2 = post;
      for (auto a = adj[v].cbegin(); a != a2; ++a) {
        if (a != aj) pre2 = join(pre2, h0[*a]);
      }
      if (a2 != ae && w[*a2] == w[*aj] + 1) {
        auto a3 = a2;
        do ++a3;
        while (a3 != ae && w[*a3] == w[*a2]);
        for (auto a = ae; a != a3;) post2 = join(h0[*--a], post2);
        ss.push_back(split{&*a2, &*a2 + (a3 - a2), pre2, post2});
        genh(*aj, hash(0), hash(1), -1);
        ss.pop_back();
      } else {
        for (auto a = ae; a != a2;) post2 = join(h0[*--a], post2);
        pre2 = join(pre2, hash(0));
        post2 = join(hash(1), post2);
        genh(*aj, pre2, post2, -1);
      }
    }
  };
  if (ecent) {
    genh0(center[0]);
    genh0(center[1]);
    for (int i : {0, 1}) {
      int c = center[i];
      adj[c].push_back(center[i ^ 1]);
      genh(c, hash(0, 0), hash(0, 0), n / 2);
      adj[c].pop_back();
    }
  } else {
    int c = center[0];
    genh0(c);
    genh(c, hash(0, 0), hash(0, 0), n / 2);
    for (auto i = adj[c].size(); i--;) {
      int c2 = adj[c][i];
      if (w[c2] != n / 2) continue;
      adj[c].erase(adj[c].begin() + i);
      genh0(c, false);
      genh(c2, hash(0, 0), hash(0, 0), -1);
      adj[c].insert(adj[c].begin() + i, c2);
      hconcat(c2, h0[c]);
    }
  }
  std::sort(hnew, hnew + n);
  int ans = 1;
  for (int i = nbad + 1; i < n; i++) {
    if (memcmp(hnew + i, hnew + i - 1, sizeof(*hnew))) ++ans;
  }
  std::cout << ans;
  return 0;
}
