import static java.math.BigInteger.*;
import static java.util.Arrays.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

public class A {

	final int MOD = (int)1e9 + 7;
	final double eps = 1e-12;
	final int INF = (int)1e9;

	public A () {
		int N = sc.nextInt();
		int K = sc.nextInt();
		Long [] A = sc.nextLongs();

		sort(A);
		Set<Long> S = new HashSet<Long>();

		for (long a : A) {
			if (a % K == 0 && S.contains(H(a/K)))
				continue;
			S.add(H(a));
		}

		int res = S.size();
		exit(res);
	}

	long P = probablePrime(60, new Random()).longValue();
	long Q = probablePrime(60, new Random()).longValue();

	long H(long x) {
		return (P*x) % Q;
	}

	////////////////////////////////////////////////////////////////////////////////////

	/* Dear hacker, don't bother reading below this line, unless you want to help me debug my I/O routines :-) */

	static MyScanner sc = new MyScanner();

	static class MyScanner {
		public String next() {
			newLine();
			return line[index++];
		}

		public char nextChar() {
			return next().charAt(0);
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			line = null;
			return readLine();
		}

		public String [] nextStrings() {
			line = null;
			return readLine().split(" ");
		}

		public char [] nextChars() {
			return next().toCharArray();
		}

		public Integer [] nextInts() {
			String [] L = nextStrings();
			Integer [] res = new Integer [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Integer.parseInt(L[i]);
			return res;
		}

		public Long [] nextLongs() {
			String [] L = nextStrings();
			Long [] res = new Long [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Long.parseLong(L[i]);
			return res;
		}

		public Double [] nextDoubles() {
			String [] L = nextStrings();
			Double [] res = new Double [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Double.parseDouble(L[i]);
			return res;
		}

		public String [] next (int N) {
			String [] res = new String [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.next();
			return res;
		}

		public Integer [] nextInt (int N) {
			Integer [] res = new Integer [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInt();
			return res;
		}

		public Long [] nextLong (int N) {
			Long [] res = new Long [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLong();
			return res;
		}

		public Double [] nextDouble (int N) {
			Double [] res = new Double [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDouble();
			return res;
		}

		public String [][] nextStrings (int N) {
			String [][] res = new String [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextStrings();
			return res;
		}

		public Integer [][] nextInts (int N) {
			Integer [][] res = new Integer [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInts();
			return res;
		}

		public Long [][] nextLongs (int N) {
			Long [][] res = new Long [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLongs();
			return res;
		}

		public Double [][] nextDoubles (int N) {
			Double [][] res = new Double [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDoubles();
			return res;
		}

		//////////////////////////////////////////////

		private boolean eol() {
			return index == line.length;
		}

		private String readLine() {
			try {
				return r.readLine();
			} catch (Exception e) {
				throw new Error(e);
			}
		}
		private final BufferedReader r;

		MyScanner () {
			this(new BufferedReader(new InputStreamReader(System.in)));
		}

		MyScanner(BufferedReader r) {
			try {
				this.r = r;
				while (!r.ready())
					Thread.sleep(1);
				start();
			} catch (Exception e) {
				throw new Error(e);
			}
		}

		private String [] line;
		private int index;

		private void newLine() {
			if (line == null || eol()) {
				line = readLine().split(" ");
				index = 0;
			}
		}
	}

	static void print(Object o, Object... a) {
		printDelim(" ", o, a);
	}

	static void cprint(Object o, Object... a) {
		printDelim("", o, a);
	}

	static void printDelim (String delim, Object o, Object... a) {
		pw.println(build(delim, o, a));
	}

	static void exit (Object o, Object... a) {
		print(o, a);
		exit();
	}

	static void exit () {
		pw.close();
		System.out.flush();
		System.err.println("------------------");
		System.err.println("Time: " + ((millis() - t) / 1000.0));
		System.exit(0);
	}

	void NO() {
		throw new Error("NO!");
	}

	////////////////////////////////////////////////////////////////////////////////////

	static String build(String delim, Object o, Object... a) {
		StringBuilder b = new StringBuilder();
		append(b, o, delim);
		for (Object p : a)
			append(b, p, delim);
		return b.toString().trim();
	}

	static void append(StringBuilder b, Object o, String delim) {
		if (o.getClass().isArray()) {
			int L = Array.getLength(o);
			for (int i = 0; i < L; ++i)
				append(b, Array.get(o, i), delim);
		} else if (o instanceof Iterable<?>) {
			for (Object p : (Iterable<?>)o)
				append(b, p, delim);
		} else
			b.append(delim).append(o);
	}

	////////////////////////////////////////////////////////////////////////////////////

	public static void main(String[] args) {
		new A();
		exit();
	}

	static void start() {
		t = millis();
	}

	static PrintWriter pw = new PrintWriter(System.out);

	static long t;

	static long millis() {
		return System.currentTimeMillis();
	}
}


import java.util.*;
import java.io.*;
import java.awt.Point;
import java.math.BigInteger;

import static java.lang.Math.*;

// Solution is at the bottom of code

public class _AAAA implements Runnable{

	final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

	BufferedReader in;
	OutputWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args){
		new Thread(null, new _AAAA(), "", 128 * (1L << 20)).start();
	}

	/////////////////////////////////////////////////////////////////////

	void init() throws FileNotFoundException{
		Locale.setDefault(Locale.US);

		if (ONLINE_JUDGE){
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new OutputWriter(System.out);
		}else{
			in = new BufferedReader(new FileReader("input.txt"));
			out = new OutputWriter("output.txt");
		}
	}

	////////////////////////////////////////////////////////////////

	long timeBegin, timeEnd;

	void time(){
		timeEnd = System.currentTimeMillis();
		System.err.println("Time = " + (timeEnd - timeBegin));
	}

	void debug(Object... objects){
		if (ONLINE_JUDGE){
			for (Object o: objects){
				System.err.println(o.toString());
			}
		}
	}

	/////////////////////////////////////////////////////////////////////

	public void run(){
		try{
			timeBegin = System.currentTimeMillis();
			Locale.setDefault(Locale.US);

			init();
			solve();

			out.close();
			time();
		}catch (Exception e){
			e.printStackTrace(System.err);
			System.exit(-1);
		}
	}

	/////////////////////////////////////////////////////////////////////

	String delim = " ";

	String readString() throws IOException{
		while(!tok.hasMoreTokens()){
			try{
				tok = new StringTokenizer(in.readLine());
			}catch (Exception e){
				return null;
			}
		}

		return tok.nextToken(delim);
	}

	String readLine() throws IOException{
		return in.readLine();
	}

	/////////////////////////////////////////////////////////////////

	final char NOT_A_SYMBOL = '\0';

	char readChar() throws IOException{
		int intValue = in.read();

		if (intValue == -1){
			return NOT_A_SYMBOL;
		}

		return (char) intValue;
	}

	char[] readCharArray() throws IOException{
		return readLine().toCharArray();
	}

	/////////////////////////////////////////////////////////////////

	int readInt() throws IOException{
		return Integer.parseInt(readString());
	}

	int[] readIntArray(int size) throws IOException{
		int[] array = new int[size];

		for (int index = 0; index < size; ++index){
			array[index] = readInt();
		}

		return array;
	}

	///////////////////////////////////////////////////////////////////

	long readLong() throws IOException{
		return Long.parseLong(readString());
	}

	long[] readLongArray(int size) throws IOException{
		long[] array = new long[size];

		for (int index = 0; index < size; ++index){
			array[index] = readLong();
		}

		return array;
	}

	////////////////////////////////////////////////////////////////////

	double readDouble() throws IOException{
		return Double.parseDouble(readString());
	}

	double[] readDoubleArray(int size) throws IOException{
		double[] array = new double[size];

		for (int index = 0; index < size; ++index){
			array[index] = readDouble();
		}

		return array;
	}

	/////////////////////////////////////////////////////////////////////

	Point readPoint() throws IOException{
		return new Point(readInt(), readInt());
	}

	Point[] readPointArray(int size) throws IOException{
		Point[] array = new Point[size];

		for (int index = 0; index < size; ++index){
			array[index] = readPoint();
		}

		return array;
	}

	/////////////////////////////////////////////////////////////////////

	class OutputWriter extends PrintWriter{

		final int DEFAULT_PRECISION = 12;

		int precision;
		String format, formatWithSpace;

		{
			precision = DEFAULT_PRECISION;

			format = createFormat(precision);
			formatWithSpace = format + " ";
		}

		public OutputWriter(OutputStream out) {
			super(out);
		}

		public OutputWriter(String fileName) throws FileNotFoundException {
			super(fileName);
		}

		public int getPrecision() {
			return precision;
		}

		public void setPrecision(int precision) {
			this.precision = precision;

			format = createFormat(precision);
			formatWithSpace = format + " ";
		}

		private String createFormat(int precision){
			return "%." + precision + "f";
		}

		@Override
		public void print(double d){
			printf(format, d);
		}

		public void printWithSpace(double d){
			printf(formatWithSpace, d);
		}

		public void printAll(double...d){
			for (int i = 0; i < d.length - 1; ++i){
				printWithSpace(d[i]);
			}

			print(d[d.length - 1]);
		}

		@Override
		public void println(double d){
			printlnAll(d);
		}

		public void printlnAll(double... d){
			printAll(d);
			println();
		}
	}

	/////////////////////////////////////////////////////////////////////

	int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

	boolean check(int index, int lim){
		return (0 <= index && index < lim);
	}

	/////////////////////////////////////////////////////////////////////

	void solve() throws IOException{
		int n = readInt();
		int k = readInt();

		Map<Long, Integer> map = new TreeMap<Long, Integer>();
		for (int i = 0; i < n; ++i){
			map.put(readLong(), i);
		}

		int ans = 0;
		boolean[] used = new boolean[n];
		for (Map.Entry<Long, Integer> e: map.entrySet()){
			if (used[e.getValue()]) continue;
			long value = e.getKey() * k;
			Integer index = map.get(value);

			if (index != null){
				used[index] = true;
			}

			++ans;
		}

		out.println(ans);
	}
}


import java.io.DataInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.TreeSet;

public class Main{

	public static void main(String[] args) throws Exception {
		Parserdoubt3 s = new Parserdoubt3(System.in);
		int n = s.nextInt();
		long k = s.nextInt();
		Long a[] = new Long[n];
		TreeSet<Long> tree = new TreeSet<Long>();
		for (int i = 0; i < a.length; i++) {
			a[i] = s.nextLong();
			tree.add(a[i]);
		}
		Arrays.sort(a);

		int ans = 0;

		for (int i = 0; i < a.length; i++) {
			if(tree.contains(a[i])){
				ans++;
				long next = a[i] * k;
				if(tree.contains(next)) tree.remove(next);
			}
		}
		System.out.println(ans);
	}

}

class Parserdoubt3 {
	final private int BUFFER_SIZE = 1 << 17;

	private DataInputStream din;
	private byte[] buffer;
	private int bufferPointer, bytesRead;

	public Parserdoubt3(InputStream in) {
		din = new DataInputStream(in);
		buffer = new byte[BUFFER_SIZE];
		bufferPointer = bytesRead = 0;
	}

	public String nextString() throws Exception {
		StringBuffer sb = new StringBuffer("");
		byte c = read();
		while (c <= ' ')
			c = read();
		do {
			sb.append((char) c);
			c = read();
		} while (c > ' ');
		return sb.toString();
	}

	public char nextChar() throws Exception {
		byte c = read();
		while (c <= ' ')
			c = read();
		return (char) c;
	}

	public int nextInt() throws Exception {
		int ret = 0;
		byte c = read();
		while (c <= ' ')
			c = read();
		boolean neg = c == '-';
		if (neg)
			c = read();
		do {
			ret = ret * 10 + c - '0';
			c = read();
		} while (c > ' ');
		if (neg)
			return -ret;
		return ret;
	}

	public long nextLong() throws Exception {
		long ret = 0;
		byte c = read();
		while (c <= ' ')
			c = read();
		boolean neg = c == '-';
		if (neg)
			c = read();
		do {
			ret = ret * 10 + c - '0';
			c = read();
		} while (c > ' ');
		if (neg)
			return -ret;
		return ret;
	}

	private void fillBuffer() throws Exception {
		bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
		if (bytesRead == -1)
			buffer[0] = -1;
	}

	private byte read() throws Exception {
		if (bufferPointer == bytesRead)
			fillBuffer();
		return buffer[bufferPointer++];
	}
}


import java.io.*;
import java.util.*;
import java.math.*;
import java.awt.geom.*;

import static java.lang.Math.*;

public class Solution implements Runnable {

	public void solve () throws Exception {
		int n = sc.nextInt();
		int k = sc.nextInt();

		TreeSet<Integer> bad = new TreeSet<>();
		int a [] = new int [n];
		for (int i = 0; i < n; i++)
			a[i] = sc.nextInt();

		Arrays.sort(a);

		int result = 0;
		for (int i = 0; i < n; i++) {
			if (!bad.contains(a[i])) {
				result++;
				long next = (long) a[i] * k;
				if (next <= 1000000000)
					bad.add((int) next);
			}
		}
		out.println(result);
	}

	BufferedReader in;
	PrintWriter out;
	FastScanner sc;

	static Throwable uncaught;

	@Override
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			sc = new FastScanner(in);
			solve();
		} catch (Throwable t) {
			Solution.uncaught = t;
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) throws Throwable {
		Thread t = new Thread(null, new Solution(), "", (1 << 26));
		t.start();
		t.join();
		if (uncaught != null) {
			throw uncaught;
		}
	}

}

class FastScanner {

	BufferedReader reader;
	StringTokenizer strTok;

	public FastScanner(BufferedReader reader) {
		this.reader = reader;
	}

	public String nextToken() throws IOException {
		while (strTok == null || !strTok.hasMoreTokens()) {
			strTok = new StringTokenizer(reader.readLine());
		}
		return strTok.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Scanner;

public class f {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		Hashtable<Long, Boolean> d = new Hashtable<Long, Boolean>();
		int n = in.nextInt(), k = in.nextInt(), size = 0, a[] = new int[n];
		for (int i = 0; i < n; i++) a[i] = in.nextInt();
		Arrays.sort(a);
		for (int i = 0; i < n; i++) {
			long x = a[i];
			if (!d.containsKey(x)) {
				d.put(x * k, true);
				size++;
			}
		}
		System.out.println(size);
	}

}


import java.io.*;
import java.util.*;
import java.math.*;

public class Main {
	public static void main(String[] args) {
		new Main().run();
	}
	void run() {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = in.nextInt(), k = in.nextInt();
		int[] a = new int[n];
		for (int i = 0; i < n; ++i)
			a[i] = in.nextInt();
		Arrays.sort(a);
		int ret = 0, it = 0;
		for (int i = 0; i < n; ++i) {
			int val = a[i] % k == 0 ? a[i] / k : -1;
			while (it < i && a[it] < val) ++it;
			if (it == i || a[it] != val) {
				++ret;
			}
			else {
				a[i] = 0;
			}
		}
		out.println(ret);

		out.close();
	}
}

class InputReader {
	BufferedReader buff;
	StringTokenizer tokenizer;

	InputReader(InputStream stream) {
		buff = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}
	boolean hasNext() {
		while (tokenizer == null || !tokenizer.hasMoreTokens())
			try {
				tokenizer = new StringTokenizer(buff.readLine());
			}
			catch (Exception e) {
				return false;
			}
		return true;
	}
	String next() {
		if (!hasNext())
			throw new RuntimeException();
		return tokenizer.nextToken();
	}
	int nextInt() { return Integer.parseInt(next()); }
	long nextLong() { return Long.parseLong(next()); }
}


import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class Main {

	Scanner in;
	static PrintWriter out;

	static class Scanner {
		StreamTokenizer in;

		Scanner(InputStream is) {
			in = new StreamTokenizer(new BufferedReader(new InputStreamReader(is)));
			in.resetSyntax();
			in.whitespaceChars(0, 32);
			in.wordChars(33, 255);
		}

		String readLine() {
			try {
				in.nextToken();
				asserT(in.ttype == StreamTokenizer.TT_WORD);
				return in.sval;
			} catch (IOException e) {
				throw new Error();
			}
		}

		int nextInt() {
			return Integer.parseInt(readLine());
		}
	}

	void solve() {
		int n = in.nextInt();
		long k = in.nextInt();
		int ar[] = new int[n];
		TreeMap <Integer, Integer> nums = new TreeMap<Integer, Integer>();
		for (int i = 0; i < n; i++) {
			ar[i] = in.nextInt();
			nums.put(ar[i], i);
		}

		if (k == 1) {
			out.println(n);
			return;
		}

		int next[] = new int[n];
		Arrays.fill(next, -1);

		int count = 0;

		for (int i = 0; i < n; i++) {
			long val = ar[i] * k;
			int intVal = (int)val;
			if (intVal == val) {
				if (nums.containsKey(intVal)) {
					int idx = nums.get(intVal);
					next[i] = idx;
					continue;
				}
			}

			if (ar[i] % k == 0) {
				intVal = ar[i] / (int)k;

				if (nums.containsKey(intVal)) {
					continue;
				}
			}

			count++;
		}

		for (int i = 0; i < n; i++) {
			int curr = nums.pollFirstEntry().getValue();
			boolean odd = false;
			while (next[curr] != -1) {
				if (!odd) {
					count++;
				}
				int to = next[curr];
				next[curr] = -1;
				curr = to;
				odd = !odd;

				if (next[curr] == -1) {
					if (!odd) {
						count++;
					}
				}
			}
		}
		out.println(count);
	}

	static void asserT(boolean e) {
		if (!e) {
			throw new Error();
		}
	}

	public void run() {
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);

		try {
			solve();
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) {
		new Main().run();
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ProblemA {

	public static void main(String[] args) throws IOException {
		BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);

		String[] data = s.readLine().split(" ");
		int n = Integer.valueOf(data[0]);
		int k = Integer.valueOf(data[1]);

		long[] a = new long[n];
		String[] ai = s.readLine().split(" ");
		for (int i = 0 ; i < n ; i++) {
			a[i] = Integer.valueOf(ai[i]);
		}
		for (int i = 0 ; i < n ; i++) {
			int tm = (int)(Math.random() * n);
			long tmp = a[tm];
			a[tm] = a[i];
			a[i] = tmp;
		}
		Arrays.sort(a);

		Set<Long> invalid = new HashSet<Long>();
		int cnt = 0;
		for (int i = 0 ; i < n ; i++) {
			if (!invalid.contains(a[i])) {
				cnt++;
				invalid.add(a[i] * k);
			}
		}
		out.println(cnt);
		out.flush();
	}

	public static void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class A {

	public static void main(String[] args) throws IOException {
		InputReader in = new InputReader();
		int n = in.nextInt();
		long k = in.nextInt();
		Long[] a = new Long[n];
		for(int i = 0 ; i < n;i++)a[i]=in.nextLong();
		if(k==1)System.out.println(n);
		else{
			int res = 0;
			Arrays.sort(a);
			boolean[] v = new boolean[n];
			for(int i = 0 ; i < n;i++){
				if(!v[i]){
					long cur = a[i];
					int cnt = 1;
					while(true){
						int idx = Arrays.binarySearch(a, cur*k);
						if(idx<0){
							res+= cnt/2 + cnt%2;
							break;
							}
						v[idx]=true;
						cur = a[idx];
						cnt++;
					}
				}
			}
			System.out.println(res);
		}
	}

	static class InputReader {
		BufferedReader in;
		StringTokenizer st;

		public InputReader() throws IOException {
			in = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer(in.readLine());
		}

		public String next() throws IOException {
			while (!st.hasMoreElements())
				st = new StringTokenizer(in.readLine());
			return st.nextToken();
		}

		public int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}


import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author NAO93
 */
public class a {
    public static void main(String[] args) {
        Scanner in = new  Scanner(System.in);
        int n = in.nextInt();
        long k = in.nextLong();
        Long []a = new Long[n];
        for (int i = 0; i<n; i++)
            a[i] = in.nextLong();
        HashSet<Long> hash = new HashSet<Long>();
        Arrays.sort(a);
        for (int i = 0; i<n; i++)
            if (!hash.contains(a[i])){
                hash.add(a[i] * k);
            }
        System.out.println(hash.size());
    }

}


import java.util.*;
import java.io.*;
import java.awt.Point;
import static java.lang.Math.*;

public class P274A {
    public static int i(String s) { return Integer.parseInt(s); }
    public static void main(String[] args) throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] arr = in.readLine().split(" ");
        int n = i(arr[0]);
        long k = i(arr[1]);
        long[] A = new long[n];
        arr = in.readLine().split(" ");
        for(int i=0; i<n; i++)
            A[i] = i(arr[i]);
        shuffle(A);
        Arrays.sort(A);

        Set<Long> BAN = new HashSet<Long>();
        int ans = 0;
        for(int i=0; i<n; i++) {
            if(!BAN.contains(A[i])) {
                ans++;
                BAN.add(A[i]*k);
            }
        }
        System.out.println(ans);
    }
    public static void shuffle(long[] array) {
        for (int i = array.length; i > 1; i--) {
            long temp = array[i - 1];
            int randIx = (int) (Math.random() * i);
            array[i - 1] = array[randIx];
            array[randIx] = temp;
        }
    }
}


import static java.util.Arrays.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

public class A {

	final int MOD = (int)1e9 + 7;
	final double eps = 1e-12;
	final int INF = (int)1e9;

	public A () {
		int N = sc.nextInt();
		int K = sc.nextInt();
		Long [] A = sc.nextLongs();

		sort(A);
		TreeSet<Long> S = new TreeSet<Long>();

		for (long a : A) {
			if (a % K == 0 && S.contains(a/K))
				continue;
			S.add(a);
		}

		int res = S.size();
		exit(res);
	}

	////////////////////////////////////////////////////////////////////////////////////

	/* Dear hacker, don't bother reading below this line, unless you want to help me debug my I/O routines :-) */

	static MyScanner sc = new MyScanner();

	static class MyScanner {
		public String next() {
			newLine();
			return line[index++];
		}

		public char nextChar() {
			return next().charAt(0);
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			line = null;
			return readLine();
		}

		public String [] nextStrings() {
			line = null;
			return readLine().split(" ");
		}

		public char [] nextChars() {
			return next().toCharArray();
		}

		public Integer [] nextInts() {
			String [] L = nextStrings();
			Integer [] res = new Integer [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Integer.parseInt(L[i]);
			return res;
		}

		public Long [] nextLongs() {
			String [] L = nextStrings();
			Long [] res = new Long [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Long.parseLong(L[i]);
			return res;
		}

		public Double [] nextDoubles() {
			String [] L = nextStrings();
			Double [] res = new Double [L.length];
			for (int i = 0; i < L.length; ++i)
				res[i] = Double.parseDouble(L[i]);
			return res;
		}

		public String [] next (int N) {
			String [] res = new String [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.next();
			return res;
		}

		public Integer [] nextInt (int N) {
			Integer [] res = new Integer [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInt();
			return res;
		}

		public Long [] nextLong (int N) {
			Long [] res = new Long [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLong();
			return res;
		}

		public Double [] nextDouble (int N) {
			Double [] res = new Double [N];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDouble();
			return res;
		}

		public String [][] nextStrings (int N) {
			String [][] res = new String [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextStrings();
			return res;
		}

		public Integer [][] nextInts (int N) {
			Integer [][] res = new Integer [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextInts();
			return res;
		}

		public Long [][] nextLongs (int N) {
			Long [][] res = new Long [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextLongs();
			return res;
		}

		public Double [][] nextDoubles (int N) {
			Double [][] res = new Double [N][];
			for (int i = 0; i < N; ++i)
				res[i] = sc.nextDoubles();
			return res;
		}

		//////////////////////////////////////////////

		private boolean eol() {
			return index == line.length;
		}

		private String readLine() {
			try {
				return r.readLine();
			} catch (Exception e) {
				throw new Error(e);
			}
		}
		private final BufferedReader r;

		MyScanner () {
			this(new BufferedReader(new InputStreamReader(System.in)));
		}

		MyScanner(BufferedReader r) {
			try {
				this.r = r;
				while (!r.ready())
					Thread.sleep(1);
				start();
			} catch (Exception e) {
				throw new Error(e);
			}
		}

		private String [] line;
		private int index;

		private void newLine() {
			if (line == null || eol()) {
				line = readLine().split(" ");
				index = 0;
			}
		}
	}

	static void print(Object o, Object... a) {
		printDelim(" ", o, a);
	}

	static void cprint(Object o, Object... a) {
		printDelim("", o, a);
	}

	static void printDelim (String delim, Object o, Object... a) {
		pw.println(build(delim, o, a));
	}

	static void exit (Object o, Object... a) {
		print(o, a);
		exit();
	}

	static void exit () {
		pw.close();
		System.out.flush();
		System.err.println("------------------");
		System.err.println("Time: " + ((millis() - t) / 1000.0));
		System.exit(0);
	}

	void NO() {
		throw new Error("NO!");
	}

	////////////////////////////////////////////////////////////////////////////////////

	static String build(String delim, Object o, Object... a) {
		StringBuilder b = new StringBuilder();
		append(b, o, delim);
		for (Object p : a)
			append(b, p, delim);
		return b.toString().trim();
	}

	static void append(StringBuilder b, Object o, String delim) {
		if (o.getClass().isArray()) {
			int L = Array.getLength(o);
			for (int i = 0; i < L; ++i)
				append(b, Array.get(o, i), delim);
		} else if (o instanceof Iterable<?>) {
			for (Object p : (Iterable<?>)o)
				append(b, p, delim);
		} else
			b.append(delim).append(o);
	}

	////////////////////////////////////////////////////////////////////////////////////

	public static void main(String[] args) {
		new A();
		exit();
	}

	static void start() {
		t = millis();
	}

	static PrintWriter pw = new PrintWriter(System.out);

	static long t;

	static long millis() {
		return System.currentTimeMillis();
	}
}


/* Codeforces Template */

import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {

	static long initTime;
	static final Random rnd = new Random(7777L);
	static boolean writeLog = false;

	public static void main(String[] args) throws IOException {
		initTime = System.currentTimeMillis();
		try {
			writeLog = "true".equals(System.getProperty("LOCAL_RUN_7777"));
		} catch (SecurityException e) {}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					try {
						if (new File("input.txt").exists())
							System.setIn(new FileInputStream("input.txt"));
					} catch (SecurityException e) {}
					long prevTime = System.currentTimeMillis();
					new Main().run();
					log("Total time: " + (System.currentTimeMillis() - prevTime) + " ms");
					log("Memory status: " + memoryStatus());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 24).start();
	}

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
		in.close();
	}

	/***************************************************************
	 * Solution
	 **************************************************************/

	void solve() throws IOException  {

		int n = nextInt();
		long k = nextLong();
		int[] a = nextIntArray(n);

		Set<Long> bad = new TreeSet<Long>();

		sort(a);

		int ans = 0;

		for (int x : a) {
			if (!bad.contains((long) x)) {
				bad.add(x * k);
				ans++;
			}
		}

		out.println(ans);

	}

	/***************************************************************
	 * Input
	 **************************************************************/
	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	int[] nextIntArray(int size) throws IOException {
		int[] ret = new int [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextInt();
		return ret;
	}

	long[] nextLongArray(int size) throws IOException {
		long[] ret = new long [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextLong();
		return ret;
	}

	double[] nextDoubleArray(int size) throws IOException {
		double[] ret = new double [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextDouble();
		return ret;
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}

	/***************************************************************
	 * Output
	 **************************************************************/
	void printRepeat(String s, int count) {
		for (int i = 0; i < count; i++)
			out.print(s);
	}

	void printArray(int[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(long[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array, String spec) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.printf(Locale.US, spec, array[i]);
		}
		out.println();
	}

	void printArray(Object[] array) {
		if (array == null || array.length == 0)
			return;
		boolean blank = false;
		for (Object x : array) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}

	@SuppressWarnings("rawtypes")
	void printCollection(Collection collection) {
		if (collection == null || collection.isEmpty())
			return;
		boolean blank = false;
		for (Object x : collection) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}

	/***************************************************************
	 * Utility
	 **************************************************************/
	static String memoryStatus() {
		return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() >> 20) + "/" + (Runtime.getRuntime().totalMemory() >> 20) + " MB";
	}

	static void checkMemory() {
		System.err.println(memoryStatus());
	}

	static long prevTimeStamp = Long.MIN_VALUE;

	static void updateTimer() {
		prevTimeStamp = System.currentTimeMillis();
	}

	static long elapsedTime() {
		return (System.currentTimeMillis() - prevTimeStamp);
	}

	static void checkTimer() {
		System.err.println(elapsedTime() + " ms");
	}

	static void chk(boolean f) {
		if (!f) throw new RuntimeException("Assert failed");
	}

	static void chk(boolean f, String format, Object ... args) {
		if (!f) throw new RuntimeException(String.format(format, args));
	}

	static void log(String format, Object ... args) {
		if (writeLog) System.err.println(String.format(Locale.US, format, args));
	}
}


//package round168;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class A {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), K = ni();
		int[] a = na(n);
		if(K == 1){
			out.println(n);
			return;
		}
		a = radixSort(a);
		boolean[] dead = new boolean[n];
		int ct = 0;
		for(int i = 0;i < n;i++){
			if(!dead[i]){
				ct++;
				if((long)a[i]*K<=1000000000){
					int ind = Arrays.binarySearch(a, a[i]*K);
					if(ind >= 0){
						dead[ind] = true;
					}
				}
			}
		}
		out.println(ct);
	}

	public static int[] radixSort(int[] f)
	{
		int[] to = new int[f.length];
		{
			int[] b = new int[65537];
			for(int i = 0;i < f.length;i++)b[1+(f[i]&0xffff)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < f.length;i++)to[b[f[i]&0xffff]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		{
			int[] b = new int[65537];
			for(int i = 0;i < f.length;i++)b[1+(f[i]>>>16)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < f.length;i++)to[b[f[i]>>>16]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		return f;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new A().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.math.*;
import java.util.*;
import java.lang.*;

public class Main
{
    static Input in;
    static Output out;

    public static void main(String[] args) throws IOException
    {
        in = new Input(System.in);
        out = new Output(System.out);
        run();
        out.close();
        System.exit(0);
    }

    private static void run() throws IOException
    {
        int n = in.nextInt(), k = in.nextInt();
        int[] A = new int[n];
        for (int i = 0; i < n; i++)
        {
            A[i] = in.nextInt();
        }
        Arrays.sort(A);
        int count = n;
        boolean[] hash = new boolean[n];
        for (int i = n-1; i > 0; i--)
        {
            if(!hash[i])
            {
                int a = A[i];
                if(a % k == 0)
                {
                    int p = a / k;
                    int j = Arrays.binarySearch(A, p);
                    if(j >= 0 && j < i)
                    {
                        hash[j] = true;
                        count--;
                    }
                }
            }
        }
        out.print(count);
    }
}

class Input
{
    final int SIZE = 8192;
    private InputStream in;
    private byte[] buf = new byte[SIZE];
    private int last, current, total;

    public Input(InputStream stream) throws IOException
    {
        in = stream;
        last = read();
    }

    private int read() throws IOException
    {
        if (total == -1) return -1;
        if (current >= total)
        {
            current = 0;
            total = in.read(buf);
            if (total <= 0) return -1;
        }
        return buf[current++];
    }

    private void advance() throws IOException
    {
        while (true)
        {
            if (last == -1) return;
            if (!isValidChar(last)) last = read();
            else break;
        }
    }

    private boolean isValidChar(int c)
    {
        return c > 32 && c < 127;
    }

    public boolean isEOF() throws IOException
    {
        advance();
        return last == -1;
    }

    public String nextString() throws IOException
    {
        advance();
        if (last == -1) throw new EOFException();
        StringBuilder s = new StringBuilder();
        while (true)
        {
            s.appendCodePoint(last);
            last = read();
            if (!isValidChar(last)) break;
        }
        return s.toString();
    }

    public String nextLine() throws IOException
    {
        if (last == -1) throw new EOFException();
        StringBuilder s = new StringBuilder();
        while (true)
        {
            s.appendCodePoint(last);
            last = read();
            if (last == '\n' || last == -1) break;
        }
        return s.toString();
    }

    public String nextLine(boolean ignoreIfEmpty) throws IOException
    {
        if (!ignoreIfEmpty) return nextLine();
        String s = nextLine();
        while (s.trim().length() == 0) s = nextLine();
        return s;
    }

    public int nextInt() throws IOException
    {
        advance();
        if (last == -1) throw new EOFException();
        int n = 0, s = 1;
        if (last == '-')
        {
            s = -1;
            last = read();
            if (last == -1) throw new EOFException();
        }
        while (true)
        {
            n = n * 10 + last - '0';
            last = read();
            if (!isValidChar(last)) break;
        }
        return n * s;
    }

    public long nextLong() throws IOException
    {
        advance();
        if (last == -1) throw new EOFException();
        int s = 1;
        if (last == '-')
        {
            s = -1;
            last = read();
            if (last == -1) throw new EOFException();
        }
        long n = 0;
        while (true)
        {
            n = n * 10 + last - '0';
            last = read();
            if (!isValidChar(last)) break;
        }
        return n * s;
    }

    public BigInteger nextBigInt() throws IOException
    {
        return new BigInteger(nextString());
    }

    public char nextChar() throws IOException
    {
        advance();
        return (char) last;
    }

    public double nextDouble() throws IOException
    {
        advance();
        if (last == -1) throw new EOFException();
        int s = 1;
        if (last == '-')
        {
            s = -1;
            last = read();
            if (last == -1) throw new EOFException();
        }
        double n = 0;
        while (true)
        {
            n = n * 10 + last - '0';
            last = read();
            if (!isValidChar(last) || last == '.') break;
        }
        if (last == '.')
        {
            last = read();
            if (last == -1) throw new EOFException();
            double m = 1;
            while (true)
            {
                m = m / 10;
                n = n + (last - '0') * m;
                last = read();
                if (!isValidChar(last)) break;
            }
        }
        return n * s;
    }

    public BigDecimal nextBigDecimal() throws IOException
    {
        return new BigDecimal(nextString());
    }

    public void close() throws IOException
    {
        in.close();
        in = null;
    }

}

class Output
{
    final int SIZE = 8192;
    private Writer out;
    private char cb[] = new char[SIZE];
    private int nChars = SIZE, nextChar = 0;
    private char lineSeparator = '\n';

    public Output(OutputStream stream)
    {
        out = new OutputStreamWriter(stream);
    }

    void flushBuffer() throws IOException
    {
        if (nextChar == 0) return;
        out.write(cb, 0, nextChar);
        nextChar = 0;
    }

    void write(int c) throws IOException
    {
        if (nextChar >= nChars) flushBuffer();
        cb[nextChar++] = (char) c;
    }

    void write(String s, int off, int len) throws IOException
    {
        int b = off, t = off + len;
        while (b < t)
        {
            int a = nChars - nextChar, a1 = t - b;

            int d = a < a1 ? a : a1;
            s.getChars(b, b + d, cb, nextChar);
            b += d;
            nextChar += d;
            if (nextChar >= nChars) flushBuffer();
        }
    }

    void write(String s) throws IOException
    {
        write(s, 0, s.length());
    }

    public void print(Object obj) throws IOException
    {
        write(String.valueOf(obj));
    }

    public void println(Object obj) throws IOException
    {
        write(String.valueOf(obj));
        write(lineSeparator);
    }

    public void printf(String format, Object... obj) throws IOException
    {
        write(String.format(format, obj));
    }

    public void close() throws IOException
    {
        flushBuffer();
        out.close();
        out = null;
    }
}


import java.io.*;
import java.util.*;
import java.math.*;

public class A implements Runnable {
	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer st;
	static Random rnd;

	void solve() throws IOException {
		int n = nextInt();
		long k = nextLong();

		if (k == 1) {
			out.println(n);
		} else {

			TreeMap<Long, ArrayList<Integer>> numbers = new TreeMap<Long, ArrayList<Integer>>();

			for (int i = 0; i < n; i++) {
				long m = nextLong();
				int howMuch = 0;

				while (m % k == 0) {
					m /= k;
					++howMuch;
				}

				if (!numbers.containsKey(m)) {
					numbers.put(m, new ArrayList<Integer>());
				}

				numbers.get(m).add(howMuch);
			}

			int res = 0;

			for (ArrayList<Integer> oneGroup : numbers.values()) {
				res += parseOneGroup(oneGroup);
			}

			out.println(res);
		}
	}

	private int parseOneGroup(ArrayList<Integer> oneGroup) {
		Collections.sort(oneGroup);

		int res = 0, prevValue = Integer.MIN_VALUE;

		for (int i = 0; i < oneGroup.size(); i++) {
			int curValue = oneGroup.get(i);

			if (prevValue + 1 != curValue) {
				++res;
				prevValue = curValue;
			}
		}

		return res;
	}

	public static void main(String[] args) {
		new A().run();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			rnd = new Random();

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(42);
		}
	}

	String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String line = in.readLine();

			if (line == null)
				return null;

			st = new StringTokenizer(line);
		}

		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    //http://www.codeforces.com/contest/275/problem/C

    public static void main(String[] args) throws NumberFormatException, IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        int num = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine(), " ");

        if (k == 1) System.out.println(num);
        else {
            Set<Integer> set = new TreeSet<Integer>();
            Set<Integer> bad = new TreeSet<Integer>();
            int sel;

            int[] arr = new int[num];
            for (int i = 0; i < num; i++) {
                arr[i] = Integer.parseInt((st.nextToken()));
            }

            shuffle(arr);
            Arrays.sort(arr);

            for (int i = 0; i < num; i++) {
                sel = arr[i];
                if (sel % k != 0) {
                    set.add(sel);
                    bad.add(sel * k);
                }
                if (!bad.contains(sel) && !set.contains(sel / k)) {
                    bad.add(sel * k);
                    set.add(sel);
                }
            }

            System.out.println(set.size());
        }
    }

    public static void shuffle(int[] arr) {
        Random rand = new Random();
        for (int i = arr.length - 1; i >= 0; --i) {
            int pos = rand.nextInt(i + 1);
            int aux = arr[i];
            arr[i] = arr[pos];
            arr[pos] = aux;
        }
    }
}


import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

public class CF274A {

    public static void main(String[] args) throws Exception {
        new CF274A().solve();
    }

    private void solve() throws Exception {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long k = sc.nextInt();
        Integer[] a = new Integer[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        Arrays.sort(a);
        HashSet<Integer> used = new HashSet<>(n);
        int count = 0;
        for (int i = 0; i < n; i++) {
            Integer v = a[i];
            if (!used.contains(v)) {
                count++;
                long next = v * k;
                if (next <= 1000000000) used.add((int) next);
            }
        }
        System.out.println(count);
    }

}


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        long k = in.nextLong();
        long[] a = new long[n];
        for (int i = 0; i < n; ++i) a[i] = in.nextLong();
        Arrays.sort(a);
        boolean[] take = new boolean[n];
        Arrays.fill(take, true);
        int j = 0;
        int res = n;
        for (int i = 0; i < n; ++i) {
            while (j < i && a[j] * k < a[i]) ++j;
            if (j < i && take[j] && a[j] * k == a[i]) {
                take[i] = false;
                --res;
            }
        }
        out.println(res);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    }


import static java.lang.Math.*;

import java.io.*;
import java.util.*;

public class Template {
	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String next() {
		while (st==null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(in.readLine());
			} catch (Exception e) {}
		}
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(next());
	}

	long nextLong() {
		return Long.parseLong(next());
	}

	double nextDouble() {
		return Double.parseDouble(next());
	}

	class Point implements Comparable<Point> {
		int x, y;
		public Point(int x, int y) {
			this.x=x;
			this.y=y;
		}
		public int compareTo(Point o) {
			return x-o.x;
		}

		public String toString() {
			return x + " " + y;
		}
	}

	public void run() throws Exception {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		Long start = System.currentTimeMillis();
			int n = nextInt();
			long k = nextLong();

			long[] a = new long[n];
			TreeMap<Long, Integer> st  = new TreeMap<Long, Integer>();

			for (int i=0; i<n; i++) {
				a[i] = nextLong();
				st.put(a[i], 1);
			}

			Arrays.sort(a);

			for (int i=0; i<n; i++) {
				if (a[i] % k == 0) {
					long x = a[i] / k;
					if (st.containsKey(x)) {
						int y = st.get(x);
						st.remove(a[i]);
						st.put(a[i], y + 1);
					}
				}
			}

			int ans = 0;
			for (int i=0; i<n; i++) {
				//System.err.println(a[n-i-1] + " " + st.get(a[n-i-1]));
				ans+=(st.get(a[n-i-1]) + 1) / 2;
				if (a[n-i-1] % k == 0) {
					long x = a[n-i-1] / k;
					if (st.containsKey(x)) {
						//System.err.println(x);
						st.remove(x);
						st.put(x, 0);
					}
				}
			}

			out.println(ans);

		Long end = System.currentTimeMillis();
		out.close();
	}

	public static void main(String[] args) throws Exception {
		new Template().run();
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;

public class A {
    static int[] parent;

    public static int find(int x) {
        if (x == parent[x])
            return x;
        return parent[x] = find(parent[x]);
    }

    public static void union(int x, int y) {
        int px = find(x);
        int py = find(y);
        if (px != py) {
            parent[py] = px;
        }
    }

    public static void main(String[] args) throws Exception {
        int numCnt = (int) nextLong();
        long k = nextLong();
        parent = new int[numCnt];
        for (int i = 0; i < parent.length; i++) {
            parent[i] = i;
        }
        Long[] ar=new Long[numCnt];
        for (int i = 0; i < numCnt; i++) {
            ar[i] = nextLong();
        }
        Arrays.sort(ar);
        for (int i = 0; i < ar.length; i++) {
            long req = ar[i] * k;
            int l=0,h=ar.length,mid;
            while(l<h){
                mid=l+(h-l)/2;
                if(ar[mid]<req){
                    l=mid+1;
                }else{
                    h=mid;
                }
            }
            if(l<ar.length&&ar[l]==req){
                union(i,l);
            }
        }
        int[] count = new int[numCnt];
        for (int i = 0; i < parent.length; i++) {
            count[find(i)]++;
        }
        int res = 0;
        for (int i = 0; i < numCnt; i++) {
            res += (int) ((count[i] + 1) / 2.0);
        }
        System.out.println(res);
    }

    static BufferedReader br = new BufferedReader(new InputStreamReader(
            System.in));
    static StringTokenizer tokenizer = new StringTokenizer("");

    static long nextLong() throws Exception {
        return Long.parseLong(next());
    }

    static double nextDouble() throws Exception {
        return Double.parseDouble(next());
    }

    static String next() throws Exception {
        while (true) {
            if (tokenizer.hasMoreTokens()) {
                return tokenizer.nextToken();
            }
            String s = br.readLine();
            if (s == null) {
                return null;
            }
            tokenizer = new StringTokenizer(s);
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Random;
import java.util.InputMismatchException;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author emotionalBlind
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int N = in.readInt();
        long K = in.readLong();
        long[] a = new long[N];
        for (int i = 0; i < N; ++i) {
            a[i] = in.readLong();
        }
        ArrayShuffler s = new ArrayShuffler();
        s.shuffle(a);
        Arrays.sort(a);
        boolean[] taken = new boolean[N];
        Arrays.fill(taken, true);
        int i = 0;
        int j = i + 1;
        int res = N;
        while (i < a.length) {
            if (taken[i] == false) {
                i++;
                if (j <= i) j = i + 1;
                continue;
            }
            while (j < a.length && a[j] < a[i] * K) {
                j++;
            }
            if (j < a.length) {
                if (a[j] == a[i] * K) {
                    taken[j] = false;
                    res--;
                }
            }
            i++;
            if (j <= i) j = i + 1;
        }
        out.printLine(res);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        // InputMismatchException -> UnknownError
        if (numChars == -1)
            throw new UnknownError();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new UnknownError();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        } else if (c == '+') {
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public static boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    }

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(outputStream);
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

class ArrayShuffler {
    static Random random = new Random(7428429L);

    public void shuffle(long[] p) {
        for (int i = 0; i < p.length; ++i) {
            int j = i + random.nextInt(p.length - i);
            long temp = p[i];
            p[i] = p[j];
            p[j] = temp;
        }
    }

    }


import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Random;
import java.util.TreeSet;

/**
 * Actual solution is at the top, in class Solver
 */
final public class Main implements Runnable {
	private static String[] args;

	public static void main(String[] args) {
		Main.args = args;
		new Thread(null, new Main(), "MyRunThread", 1 << 27).start();
	}

	//@Override
	public void run() {
		long time_beg = -1;
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		if (args.length > 0 && args[0].equals("outside")) {
			time_beg = System.currentTimeMillis();
			try {
				inputStream = new FileInputStream("IO/in.txt");
//				outputStream = new FileOutputStream("IO/out.txt");
			} catch (Exception e) {
				System.err.println(e);
				System.exit(1);
			}
		} else {
			try {
//				inputStream = new FileInputStream("IO/in.txt");
//				outputStream = new FileOutputStream("IO/out.txt");
			} catch (Exception e) {
				System.err.println(e);
				System.exit(1);
			}
		}

		Solver s = new Solver();
		s.in = new InputReader(inputStream);
		s.out = new OutputWriter(outputStream);
		if (args.length > 0 && args[0].equals("outside")) {
			s.dout = new DebugWriter(s.out);
		}

		s.solve();

		if (args.length > 0 && args[0].equals("outside")) {
			s.dout.printFormat("*** Total time: %.3f ***\n", (System.currentTimeMillis() - time_beg) / 1000.0);
		}

		s.out.close();
	}
}

final class Solver {
	InputReader in;
	OutputWriter out;
	DebugWriter dout;

	public void solve() {
		int n = in.readInt();
		int k = in.readInt();

		TreeSet<Integer> q = new TreeSet<Integer>();
		int[] mas = new int[n];
		for (int i = 0; i < n; ++i) {
			mas[i] = in.readInt();
			if (mas[i] % k != 0)
				q.add(mas[i]);
		}

//		SequenceUtils.quickSort(mas);
		Arrays.sort(mas);

		for (int i = 0; i < n; ++i)
			if (mas[i] % k == 0 && !q.contains(mas[i] / k))
				q.add(mas[i]);

		out.printLine(q.size());
	}
}

final class InputReader {
	private boolean finished = false;

	private InputStream stream;
	private byte[] buf = new byte[1 << 10];
	private int curChar;
	private int numChars;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	private int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int peek() {
		if (numChars == -1)
			return -1;
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				return -1;
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public static boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}
}

final class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream), 1 << 10));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(Object... objects) {
		print(objects);
		writer.println();
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

	public void print(char[] objects) {
		writer.print(objects);
	}

	public void printLine(char[] objects) {
		writer.println(objects);
	}

	public void printLine(char[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(int[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(int[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(int[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(short[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(short[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(short[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(long[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(long[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(long[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(double[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(double[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(double[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(byte[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(byte[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(byte[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void print(boolean[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void printLine(boolean[] objects) {
		print(objects);
		writer.println();
	}

	public void printLine(boolean[][] objects) {
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
	}

	public void close() {
		writer.close();
	}

	public void flush() {
		writer.flush();
	}
}

final class DebugWriter {
	private final OutputWriter writer;

	public DebugWriter(OutputWriter writer) {
		this.writer = writer;
	}

	private void printDebugMessage() {
		writer.print("DEBUG:\t");
	}

	public void printLine(Object... objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printFormat(String format, Object... objects) {
		flush();
		printDebugMessage();
		writer.printFormat(format, objects);
		flush();
	}

	public void printLine(char[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(char[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(double[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(double[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(int[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(int[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(short[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(short[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(long[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(long[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(byte[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(byte[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void printLine(boolean[] objects) {
		flush();
		printDebugMessage();
		writer.printLine(objects);
		flush();
	}

	public void printLine(boolean[][] objects) {
		flush();
		for (int i = 0; i < objects.length; ++i)
			printLine(objects[i]);
		flush();
	}

	public void flush() {
		writer.flush();
	}
}

interface Graph {
	// add vertexes
	public void addVertexes(int amount);

	// add edge
	public void addEdge(int source, int destination, boolean directed);

	public void addEdge(int source, int destination, boolean directed, long weight);

	public void addEdge(int source, int destination, long capacity);

	public void addEdge(int source, int destination, long weight, long capacity);

	// iterate through incident edges
	public int getFirstEdge(int source);

	public boolean hasNextEdge(int id);

	public int getNextEdge(int id);

	// graph info
	public int getVertexCount();

	public int getEdgeCount();

	public void show(DebugWriter writer);

	// simple edge info
	public int getSource(int id);

	public int getDestination(int id);

	public int getColor(int id);

	public void setColor(int id, int color);

	public boolean hasReverseEdge(int id);

	public int getReverseEdge(int id);

	public String edgeToString(int id);

	// weighted edge info
	public long getWeight(int id);

	public void setWeight(int id, long weight);

	// flow edge info
	public long getCapacity(int id);

	public void addCapacity(int id, long capacity);

	public long getFlow(int id);

	public void pushFlow(int id, long flow);
}

class GraphSimple implements Graph {
	protected int[] firstEdge;
	protected int[] nextEdge;
	protected int vertexCount = 0;
	protected int edgeCount = 0;

	protected int[] reverseEdge;
	protected int[] source;
	protected int[] destination;
	protected int[] color;

	public GraphSimple() {
		this(16, 16);
	}

	public GraphSimple(int vertexCapacity, int edgeCapacity) {
		firstEdge = new int[vertexCapacity];
		nextEdge = new int[edgeCapacity];

		reverseEdge = new int[edgeCapacity];
		source = new int[edgeCapacity];
		destination = new int[edgeCapacity];
		color = new int[edgeCapacity];
	}

	protected void ensureVertexCapacity(int size) {
	}

	protected void ensureEdgeCapacity(int size) {
	}

	// add vertexes
	@Override
	public void addVertexes(int amount) {
		ensureVertexCapacity(vertexCount + amount);
		for (int i = 0; i < amount; ++i)
			firstEdge[i + vertexCount] = -1;
		vertexCount += amount;
	}

	// add edge
	@Override
	public void addEdge(int source, int destination, boolean directed) {
		if (source >= vertexCount || destination >= vertexCount)
			throw new ArrayIndexOutOfBoundsException("wrong vertex's number");

		ensureEdgeCapacity(edgeCount + 2);
		nextEdge[edgeCount] = firstEdge[source];
		firstEdge[source] = edgeCount;

		this.source[edgeCount] = source;
		this.destination[edgeCount] = destination;
		this.color[edgeCount] = -1;

		if (directed) reverseEdge[edgeCount++] = -1;
		else {
			reverseEdge[edgeCount] = edgeCount + 1;
			++edgeCount;

			nextEdge[edgeCount] = firstEdge[destination];
			firstEdge[destination] = edgeCount;

			this.source[edgeCount] = destination;
			this.destination[edgeCount] = source;
			this.color[edgeCount] = -1;

			reverseEdge[edgeCount] = edgeCount - 1;
			++edgeCount;
		}
	}

	@Override
	public void addEdge(int source, int destination, boolean directed, long weight) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void addEdge(int source, int destination, long capacity) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void addEdge(int source, int destination, long weight, long capacity) {
		throw new UnsupportedOperationException();
	}

	// iterate through incident edges
	@Override
	public int getFirstEdge(int source) {
		if (source >= vertexCount)
			throw new ArrayIndexOutOfBoundsException("wrong vertex's number");
		return firstEdge[source];
	}

	@Override
	public boolean hasNextEdge(int id) {
		return id != -1;
	}

	@Override
	public int getNextEdge(int id) {
		return nextEdge[id];
	}

	// graph info
	@Override
	public int getVertexCount() {
		return vertexCount;
	}

	@Override
	public int getEdgeCount() {
		return edgeCount;
	}

	@Override
	public void show(DebugWriter writer) {
		writer.printLine("Graph:");
		for (int i = 0; i < getVertexCount(); ++i) {
			writer.printLine("\tincident to vertex [" + i + "]: ");
			for (int id = getFirstEdge(i); hasNextEdge(id); id = getNextEdge(id))
				writer.printLine("\t\t" + edgeToString(id));
		}
	}

	// simple edge info
	@Override
	public int getSource(int id) {
		return source[id];
	}

	@Override
	public int getDestination(int id) {
		return destination[id];
	}

	@Override
	public int getColor(int id) {
		return color[id];
	}

	@Override
	public void setColor(int id, int color) {
		this.color[id] = color;
	}

	@Override
	public boolean hasReverseEdge(int id) {
		return reverseEdge[id] != -1;
	}

	@Override
	public int getReverseEdge(int id) {
		if (reverseEdge[id] == -1)
			throw new NoSuchFieldError();
		return reverseEdge[id];
	}

	@Override
	public String edgeToString(int id) {
		return "<(" + getSource(id) + " -> " + getDestination(id) + ") color : " + getColor(id) + ">";
	}

	// weighted edge info
	@Override
	public long getWeight(int id) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setWeight(int id, long weight) {
		throw new UnsupportedOperationException();
	}

	// flow edge info
	@Override
	public long getCapacity(int id) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void addCapacity(int id, long capacity) {
		throw new UnsupportedOperationException();
	}

	@Override
	public long getFlow(int id) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void pushFlow(int id, long flow) {
		throw new UnsupportedOperationException();
	}
}

abstract class SequenceUtils {
	// swap
	public final static <T> void swap(List<T> sequence, int j, int i) {
		T tmp = sequence.get(j);
		sequence.set(j, sequence.get(i));
		sequence.set(i, tmp);
	}

	public final static <T> void swap(T[] sequence, int j, int i) {
		T tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(int[] sequence, int j, int i) {
		int tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(long[] sequence, int j, int i) {
		long tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(char[] sequence, int j, int i) {
		char tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(double[] sequence, int j, int i) {
		double tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(boolean[] sequence, int j, int i) {
		boolean tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(short[] sequence, int j, int i) {
		short tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	public final static void swap(byte[] sequence, int j, int i) {
		byte tmp = sequence[j];
		sequence[j] = sequence[i];
		sequence[i] = tmp;
	}

	// reverse
	public final static <T> void reverse(List<T> sequence) {
		for (int left = 0, right = sequence.size() - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static <T> void reverse(T[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(int[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(long[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(char[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(double[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(boolean[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(short[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	public final static void reverse(byte[] sequence) {
		for (int left = 0, right = sequence.length - 1; left < right; ++left, --right)
			swap(sequence, left, right);
	}

	// next permutation
	public final static <T extends Comparable<T>> boolean nextPermutation(List<T> sequence) {
		for (int j = sequence.size() - 2; j >= 0; --j) {
			if (sequence.get(j).compareTo(sequence.get(j + 1)) < 0) {
				reverse(sequence.subList(j + 1, sequence.size()));
				for (int i = j + 1; i < sequence.size(); ++i)
					if (sequence.get(j).compareTo(sequence.get(i)) < 0) {
						swap(sequence, j, i);
						return true;
					}
			}
		}
		return false;
	}

	public final static <T> boolean nextPermutation(List<T> sequence, Comparator<T> comparator) {
		for (int j = sequence.size() - 2; j >= 0; --j) {
			if (comparator.compare(sequence.get(j), sequence.get(j + 1)) < 0) {
				reverse(sequence.subList(j + 1, sequence.size()));
				for (int i = j + 1; i < sequence.size(); ++i)
					if (comparator.compare(sequence.get(j), sequence.get(i)) < 0) {
						swap(sequence, j, i);
						return true;
					}
			}
		}
		return false;
	}

	// random shuffle
	public final static <T> void shuffle(List<T> sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.size(); ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static <T> void shuffle(T[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(int[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(long[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(char[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(double[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(boolean[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(short[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	public final static void shuffle(byte[] sequence) {
		Random random = new Random(System.nanoTime());
		for (int i = 1; i < sequence.length; ++i)
			swap(sequence, random.nextInt(i + 1), i);
	}

	// merge sort
	public final static <T extends Comparable<T>> void mergeSort(List<T> sequence) {
		int n = sequence.size();
		T[] tmp = (T[]) new Object[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence.get(i);
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static <T extends Comparable<T>> void merge(List<T> sequence, T[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence.set(i, tmp[pRight++]);
			else if (pRight > right) sequence.set(i, tmp[pLeft++]);
			else if (tmp[pLeft].compareTo(tmp[pRight]) <= 0) sequence.set(i, tmp[pLeft++]);
			else sequence.set(i, tmp[pRight++]);
	}

	public final static <T> void mergeSort(List<T> sequence, Comparator<T> comparator) {
		int n = sequence.size();
		T[] tmp = (T[]) new Object[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence.get(i);
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1), comparator);
		}
	}

	private final static <T> void merge(List<T> sequence, T[] tmp, int left, int mid, int right, Comparator<T> comparator) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence.set(i, tmp[pRight++]);
			else if (pRight > right) sequence.set(i, tmp[pLeft++]);
			else if (comparator.compare(tmp[pLeft], tmp[pRight]) <= 0) sequence.set(i, tmp[pLeft++]);
			else sequence.set(i, tmp[pRight++]);
	}

	public final static void mergeSort(int[] sequence) {
		int n = sequence.length;
		int[] tmp = new int[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(int[] sequence, int[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(long[] sequence) {
		int n = sequence.length;
		long[] tmp = new long[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(long[] sequence, long[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(char[] sequence) {
		int n = sequence.length;
		char[] tmp = new char[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(char[] sequence, char[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(double[] sequence) {
		int n = sequence.length;
		double[] tmp = new double[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(double[] sequence, double[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(boolean[] sequence) {
		int n = sequence.length;
		boolean[] tmp = new boolean[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(boolean[] sequence, boolean[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (!tmp[pLeft] || tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(short[] sequence) {
		int n = sequence.length;
		short[] tmp = new short[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(short[] sequence, short[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	public final static void mergeSort(byte[] sequence) {
		int n = sequence.length;
		byte[] tmp = new byte[n];
		for (int step = 1; step < n; step *= 2) {
			for (int i = 0; i < n; ++i)
				tmp[i] = sequence[i];
			for (int i = 0; i + step < n; i += 2 * step)
				merge(sequence, tmp, i, i + step - 1, Math.min(i + step * 2 - 1, n - 1));
		}
	}

	private final static void merge(byte[] sequence, byte[] tmp, int left, int mid, int right) {
		int pLeft = left;
		int pRight = mid + 1;
		for (int i = left; i <= right; ++i)
			if (pLeft > mid) sequence[i] = tmp[pRight++];
			else if (pRight > right) sequence[i] = tmp[pLeft++];
			else if (tmp[pLeft] <= tmp[pRight]) sequence[i] = tmp[pLeft++];
			else sequence[i] = tmp[pRight++];
	}

	// quick sort
	public final static <T> void quickSort(List<T> sequence, Comparator<T> comparator) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.size() - 1, comparator);
	}

	private final static <T> void quickSortImplementation(List<T> sequence, int left, int right, Comparator<T> comparator) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		T value = sequence.get(left);

		while (i <= greaterThen) {
			int cmp = comparator.compare(sequence.get(i), value);
			if (cmp < 0) swap(sequence, i++, lessThen++);
			else if (cmp > 0) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1, comparator);
		quickSortImplementation(sequence, greaterThen + 1, right, comparator);
	}

	public final static <T extends Comparable<T>> void quickSort(List<T> sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.size() - 1);
	}

	private final static <T extends Comparable<T>> void quickSortImplementation(List<T> sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		T value = sequence.get(left);

		while (i <= greaterThen) {
			int cmp = sequence.get(i).compareTo(value);
			if (cmp < 0) swap(sequence, i++, lessThen++);
			else if (cmp > 0) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(int[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(int[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		int value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(long[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(long[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		long value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(char[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(char[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		char value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(double[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(double[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		double value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(boolean[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(boolean[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		boolean value = sequence[left];

		while (i <= greaterThen) {
			if (!sequence[i] && value) swap(sequence, i++, lessThen++);
			else if (sequence[i] && !value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(short[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(short[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		short value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	public final static void quickSort(byte[] sequence) {
		shuffle(sequence);
		quickSortImplementation(sequence, 0, sequence.length - 1);
	}

	private final static void quickSortImplementation(byte[] sequence, int left, int right) {
		if (left >= right) return;

		int lessThen = left;
		int greaterThen = right;
		int i = left;
		byte value = sequence[left];

		while (i <= greaterThen) {
			if (sequence[i] < value) swap(sequence, i++, lessThen++);
			else if (sequence[i] > value) swap(sequence, i, greaterThen--);
			else ++i;
		}

		quickSortImplementation(sequence, left, lessThen - 1);
		quickSortImplementation(sequence, greaterThen + 1, right);
	}

	// unique
	public static <T> ArrayList<T> unique(ArrayList<T> sequence) {
		int size = 1;
		for (int i = 1; i < sequence.size(); ++i)
			if (!sequence.get(i).equals(sequence.get(i - 1)))
				++size;

		ArrayList<T> newSequence = new ArrayList<T>(size);
		newSequence.add(sequence.get(0));

		for (int i = 1; i < sequence.size(); ++i)
			if (!sequence.get(i).equals(sequence.get(i - 1)))
				newSequence.add(sequence.get(i));

		return newSequence;
	}

	public static <T> T[] unique(T[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (!sequence[i].equals(sequence[i - 1]))
				++size;

		T[] newSequence = (T[]) new Object[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (!sequence[i].equals(sequence[i - 1]))
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static int[] unique(int[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		int[] newSequence = new int[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static long[] unique(long[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		long[] newSequence = new long[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static char[] unique(char[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		char[] newSequence = new char[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static double[] unique(double[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		double[] newSequence = new double[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static boolean[] unique(boolean[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		boolean[] newSequence = new boolean[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static short[] unique(short[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		short[] newSequence = new short[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}

	public static byte[] unique(byte[] sequence) {
		int size = 1;
		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				++size;

		byte[] newSequence = new byte[size];
		newSequence[0] = sequence[0];
		size = 0;

		for (int i = 1; i < sequence.length; ++i)
			if (sequence[i] != sequence[i - 1])
				newSequence[++size] = sequence[i];

		return newSequence;
	}
}