#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cout << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cout.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
struct dsu {
  vector<long long> par;
  vector<long long> rnk;
  vector<long long> sz;
  void init(long long n) {
    par.resize(n + 1);
    rnk.resize(n + 1);
    sz.resize(n + 1);
    for (long long i = 0; i <= n; i++) {
      par[i] = i;
      rnk[i] = 0;
      sz[i] = 1;
    }
  }
  long long findpar(long long node) {
    if (node == par[node]) return node;
    return par[node] = findpar(par[node]);
  }
  void unite(long long u, long long v) {
    long long p1 = findpar(u);
    long long p2 = findpar(v);
    if (p1 != p2) {
      long long r1 = rnk[p1];
      long long r2 = rnk[p2];
      if (r1 < r2) {
        par[p1] = p2;
        sz[p2] += sz[p1];
        sz[p1] = 0;
        rnk[p2]++;
      } else {
        par[p2] = p1;
        sz[p1] += sz[p2];
        sz[p2] = 0;
        rnk[p1]++;
      }
    }
  }
} G;
void solve() {
  long long n;
  cin >> n;
  G.init(n);
  map<long long, long long> mp;
  for (long long i = 1; i <= n; i++) {
    string s;
    cin >> s;
    for (long long j = 0; j < s.size(); j++) {
      if (mp[s[j] - 'a'] > 0) {
        G.unite(i, mp[s[j] - 'a']);
      } else {
        mp[s[j] - 'a'] = i;
      }
    }
  }
  long long ans = 0;
  for (long long i = 1; i <= n; i++) {
    if (G.findpar(i) == i) {
      ans++;
    }
  }
  cout << ans;
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long test_case = 1;
  while (test_case--) {
    solve();
  }
  return 0;
}
