#include <bits/stdc++.h>
 
#ifndef LOCAL_
#define fprintf if( false ) fprintf
#endif // LOCAL_
#define dumpi(x1) fprintf(stderr, "#%s.%d (%s) = (%d)\n", __func__, __LINE__, #x1, x1);
#define dumpii(x1, x2) fprintf(stderr, "#%s.%d (%s, %s) = (%d, %d)\n", __func__, __LINE__, #x1, #x2, x1, x2);
#define dumpiii(x1, x2, x3) fprintf(stderr, "#%s.%d (%s, %s, %s) = (%d, %d, %d)\n", __func__, __LINE__, #x1, #x2, #x3, x1, x2, x3);
#define dumpl(x1) fprintf(stderr, "#%s.%d (%s) = (%ld)\n", __func__, __LINE__, #x1, x1);
#define dumpll(x1, x2) fprintf(stderr, "#%s.%d (%s, %s) = (%ld, %ld)\n", __func__, __LINE__, #x1, #x2, x1, x2);
#define dumpd(x1) fprintf(stderr, "#%s.%d (%s) = (%lf)\n", __func__, __LINE__, #x1, x1);
#define dumpdd(x1, x2) fprintf(stderr, "#%s.%d (%s, %s) = (%lf, %lf)\n", __func__, __LINE__, #x1, #x2, x1, x2);
 
struct S002 {
  int n;
  S002& operator > (long& x) {
    n = x;
    return *this;
  }
  S002& operator >= (long& x) {
    if( scanf("%ld", &x) <= 0 ) exit(0);
    return *this;
  }
  S002& operator >= (double& x) {
    if( scanf("%lf", &x) <= 0 ) exit(0);
    return *this;
  }
  S002& operator >= (std::string& s) {
    if( not (std::cin >> s) ) exit(0);
    return *this;
  }
  template<typename a>
  S002& operator >= (std::vector<a>& v) {
    v.resize(n);
    for(long i = 0; i < n; ++i) {
      *this >= v[i];
    }
    return *this;
  }
  template<typename a, std::size_t s>
  S002& operator >= (std::array<a, s>& x) {
    for(long i = 0; i < (long)s; ++i) {
      *this >= x[i];
    }
    return *this;
  }
};

// simple edge
struct S004 {
  S004() : s(-1), d(-1) {}             
  S004(int s_, int d_) : s(s_), d(d_) {}
  long s, d;
};

// 0-indexed graph
template<typename a>
struct S005 {
  typedef a e;
  std::vector<std::vector<a>> xs;
  const std::vector<a>& ys;
  long n;
  S005(const std::vector<a>& ys_, long n_) : ys(ys_), n(n_) {
    xs.resize(n);
    for(a x : ys) {
      a y = x;
      xs[x.s].push_back(y);
    }
  }
  const std::vector<a>& operator [] (long i) const {
    return xs[i];
  }
  long v() const {
    return n;
  }
  const std::vector<a>& es() const {
    return ys;
  }
};

template<typename a>
struct S006 {
  std::vector<std::vector<long>> xs; // children
  std::vector<long> ys; // parent
  std::vector<long> zs; // component-root
  const a& g;
  S006(const a& g_) : g(g_) {
    long n = g.v();
    xs.resize(n);
    ys.resize(n);
    std::vector<bool> ws(n, false);
    for(long i = 0; i < n; ++i) {
      if( ws[i] ) continue;
      ws[i] = true;
      ys[i] = -1;
      zs.push_back(i);
      dfs(i, ws);
    }
  }
  void dfs(long i, std::vector<bool>& ws) {
    for(typename a::e x : g[i]) {
      if( ws[x.d] ) continue;
      ws[x.d] = true;
      ys[x.d] = i;
      xs[i].push_back(x.d);
      dfs(x.d, ws);
    }
  }
  // children
  std::vector<long>& c(long i) {
    return xs[i];
  }
  // parent
  long p(long i) {
    return ys[i];
  }
  // coomponent-roots
  std::vector<long>& r() {
    return zs;
  }
};

/* S006 debug
  for(long i = 0; i < n; ++i) {
    fprintf(stderr, "id : %ld\n", i);
    fprintf(stderr, "children :");
    for(long x : d.c(i)) {
      fprintf(stderr, " %ld", x);
    }
    fprintf(stderr, "\n");
    fprintf(stderr, "parent : %ld\n", d.p(i));
  }
  fprintf(stderr, "roots :");
  for(long x : d.r()) {
    fprintf(stderr, " %ld", x);
  }
  fprintf(stderr, "\n");
*/

/* union-find */
struct S007 {
  std::vector<long> xs;
  std::vector<long> ys;
  S007(long n) : xs(n), ys(n, 1) {
    for(long i = 0; i < n; ++i) {
      xs[i] = i;
    }
  }
  long find(long x) {
    if( xs[x] == x ) return x;
    return xs[x] = find(xs[x]);
  }
  void unite(long x, long y) {
    x = find(x);
    y = find(y);
    if( x == y ) return;
    if( not ( ys[x] <= ys[y] ) ) std::swap(x, y);
    xs[x] = y;
    ys[y] += ys[x];
  }
  bool same(long x, long y) {
    return find(x) == find(y);
  }
  long getN(long x) {
    return ys[x];
  }
};

/* bipartite? */
template<typename a>
struct S008 {
  std::vector<bool> xs;
  const a& g;
  S008(const a& g_) : g(g_) {
    S007 u(g.v() * 2);
    for(typename a::e x : g.es()) {
      long s = x.s;
      long d = x.d;
      u.unite(s * 2    , d * 2 + 1);
      u.unite(s * 2 + 1, d * 2    );
    }
    long n = g.v();
    xs.resize(n);
    for(long i = 0; i < n; ++i) {
      xs[i] = not u.same(i * 2, i * 2 + 1);
    }
  }
  bool f(long i) {
    return xs[i];
  }
};

struct Solver {
  long n, m;
  std::vector<std::array<long, 2>> xs;
  Solver() {
    S002 r;
    r >= n >= m >m>= xs;
  }
  void solve() {
    std::vector<S004> ys;
    for(std::array<long, 2> x : xs) {
      ys.push_back(S004(x[0]-1, x[1]-1));
      ys.push_back(S004(x[1]-1, x[0]-1));
    }
    S005<S004> g(ys, n);
    S006<S005<S004>> d(g);
    S008<S005<S004>> b(g);
    long w[3] = {};
    for(long x : d.r()) {
      if( d.c(x).size() != 0 and b.f(x) ) {
        w[0] += 1;
      }
      else if( d.c(x).size() != 0 and not b.f(x) ) {
        w[1] += 1;
      }
      else {
        w[2] += 1;
      }
    }
    // dumpll(ws[0], ws[1]);
    long res =
      2 * w[0] * w[0] +
      w[1] * w[0] + w[0] * w[1] + w[1] * w[1] +
      w[2] * (g.v() - w[2]) + (g.v() - w[2]) * w[2] + w[2] * w[2];
    printf("%ld\n", res);
  }
};
 
int main() {
  for(;;) std::unique_ptr<Solver>(new Solver())->solve();
  return 0;
}

Measured memory_bytes: 34920