Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	return &Scanner{sc}
}

func (sc *Scanner) NextInt() int {
	sc.sc.Scan()
	i, err := strconv.Atoi(sc.sc.Text())
	if err != nil {
		panic(err)
	}
	return i
}

func main() {
	sc := NewScanner()

	n := sc.NextInt()
	m := sc.NextInt()

	mp := map[int]int{}
	for i := 0; i < n; i++ {
		mp[sc.NextInt()]++
	}
	for i := 0; i < m; i++ {
		mp[sc.NextInt()]++
	}
	var and, or []int
	for k, v := range mp {
		if v >= 1 {
			or = append(or, k)
		}
		if v == 2 {
			and = append(and, k)
		}
	}
	sort.Ints(and)
	sort.Ints(or)
	fmt.Println(len(and), len(or))
	for _, v := range and {
		fmt.Println(v)
	}
	for _, v := range or {
		fmt.Println(v)
	}
}

C++: // vim: shiftwidth=2 expandtab foldmethod=marker

// include {{{
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// }}}

// debug(...) {{{
#ifdef LOCAL_DEBUG
#include "./debug.h"
#else
bool debug_enabled = false;
#define debug(...)
#define debugn(...)
#define debug_reset()
#endif

// }}}

// bin {{{
template <class T>
std::string bin(int bits, const T& x) {
  char buf[bits + 1];
  buf[bits] = '\0';
  for (int i = 0; i < bits; i++) {
    if ((x >> i) & 1) {
      buf[bits - i - 1] = '1';
    } else {
      buf[bits - i - 1] = '0';
    }
  }
  return std::string(buf);
}
std::string bin(int x) {
  if (x < 0) return bin(32, x);
  for (int i = 4; i < 31; i++) {
    int y = 1 << i;
    if (x < y) return bin(i, x);
  }
  return bin(32, x);
}
// }}}

// misc {{{
using namespace std;
template <class T, class U>

using umap = unordered_map<T, U>;
template <class T>
using uset = unordered_set<T>;

typedef long long ll;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)

template <class T>
void sort(T& arr) {  // {{{
  std::sort(arr.begin(), arr.end());
}  // }}}
template <class T, class By>
void sort_by(T& arr, By by) {  // {{{
  std::sort(arr.begin(), arr.end(), [by](auto l, auto r) { return by(l) < by(r); });
}  // }}}

template <class T>
void reverse(T& arr) {  // {{{
  std::reverse(arr.begin(), arr.end());
}  // }}}

class Random {  // {{{
 public:
  std::uniform_int_distribution<> uniform_int;
  std::mt19937 rnd;
  std::bernoulli_distribution bern_dist;
  int uniform(int l, int r) {
    return uniform_int(rnd, std::uniform_int_distribution<>::param_type(l, r));
  }
  int next(int N) {
    return uniform(0, N - 1);
  }
  int bern(double p) {
    return bern_dist(rnd, std::bernoulli_distribution::param_type(p));
  }
};  // }}}

template <class A>
ostream& out_vec(const vector<A>& x, const string& sep) {  // {{{
  rep(i, x.size()) {
    cout << x[i];
    if (i < x.size() - 1) cout << sep;
  }
  return cout;
}  // }}}

bool ends_with(const string& s, const string& x) {
  if(s.length() < x.length()) return false;
  for(int i = 0; i < x.size(); i++) {
    if(s[s.size() - 1 - i] != x[x.size() - 1 - i]) return false;
  }
  return true;
}
// }}}

// modulo {{{
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

ll modplus(ll a, ll b, ll mod) {
  ll x = ((a % mod) + (b % mod)) % mod;
  if (x < 0) x += mod;
  return x;
}

ll modminus(ll a, ll b, ll mod) {
  return modplus(a, -b, mod);
}

// }}}

class UnionFind {  // {{{
  vector<int> parent;

 public:
  UnionFind(int N) : parent(N) {
    rep(i, N) parent[i] = i;
  }

  int root(int x) {
    if (parent[x] == x)
      return x;
    else
      return parent[x] = root(parent[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) { parent[rx] = ry; }
  }
};  // }}}

// modulo {{{
// https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a
long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0) u += m;
  return u;
}

ll modfact(ll a, ll m) {
  ll x = 1;
  for (ll i = 2; i <= a; i++) {
    x *= i;
    x %= m;
  }
  return x;
}

ll mod_P(ll n, ll r, ll m) {
  ll x = 1;
  for (ll i = n - r + 1; i <= n; i++) {
    x *= i;
    x %= m;
  }
  return x;
}

ll mod_C(ll n, ll r, ll m) {
  return mod_P(n, r, m) * modinv(modfact(r, m), m) % m;
}

// }}}

// main {{{
void solve();
int main() {
  cout << setprecision(20);
  solve();
}
// }}}

void solve() {
  int n, m;
  cin >> n >> m;
  set<int> a;
  set<int> b;
  rep(i, n) {
    int x;
    cin >> x;
    a.insert(x);
  }
  rep(i, m) {
    int x;
    cin >> x;
    b.insert(x);
  }

  set<int> intersect;
  set_intersection(a.begin(), a.end(), b.begin(), b.end(), inserter(intersect, intersect.begin()));
  set<int> unions;
  set_union(a.begin(), a.end(), b.begin(), b.end(), inserter(unions, unions.begin()));

  cout << intersect.size() << ' ' << unions.size() << endl;
  for(auto i = intersect.begin(); i != intersect.end(); i++) {
    cout << *i << endl;
  }
  for(auto i = unions.begin(); i != unions.end(); i++) {
    cout << *i << endl;
  }
}

C++: #include <iostream>
#include <vector>
#include <set>
#include <iterator>
#include <algorithm>
using namespace std;

int main() {
  int n, m;
  vector<int> a, b;
  vector<int> v_or, v_and;

  cin >> n >> m;
  for(int i = 0; i < n; i++) {
    int A;
    cin >> A;
    a.push_back(A);
  }

  for(int i = 0; i < m; i++) {
    int B;
    cin >> B;
    b.push_back(B);
  }

  set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(v\
_or));
  set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_ins\
erter(v_and));
  cout << (int)v_and.size() << ' ' << (int)v_or.size() << endl;

  for (int i = 0; i < (int)v_and.size(); i++)
    cout << v_and[i] << endl;
  for (int i = 0; i < (int)v_or.size(); i++)
    cout << v_or[i] << endl;

  return 0;
}

C++: #include <iostream>
#include <vector> 
using namespace std;

int main(void){
    int n,m;
    cin >> n >> m;
    int a[n];
    int b[m];
    vector<int> dup,all;
    
    for(int i=0;i<n;i++){
        cin >> a[i];     
    }
    for(int j=0;j<m;j++){
        cin >> b[j];
    }

    int ap=0;
    int bp=0;
    int i=0;
    int a_s=0;
    int b_s=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i and b[bp]==i) a_s++;
        if(a[ap]==i or b[bp]==i) b_s++;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }
    
    cout << a_s <<" "<< b_s << endl;
    
    ap=0;
    bp=0;
    i=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i and b[bp]==i) cout<<i<<endl;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }
    
    ap=0;
    bp=0;
    i=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i or b[bp]==i) cout<<i<<endl;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }



    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    
    vector<int> A(n), B(m);
    set<int> st1, st2;
    for(int i = 0; i < n; i++){
        cin >> A[i];
        st1.insert(A[i]);
    }
    for(int i = 0; i < m; i++){
        cin >> B[i];
        if(st1.count(B[i])){
            st2.insert(B[i]);
        }
        st1.insert(B[i]);
    }

    cout << st2.size() << ' ' << st1.size() << endl;
    for(auto x : st2){
        cout << x << endl; 
    }
    for(auto x : st1){
        cout << x << endl;
    }

    return 0;
}