package main

import (
	"bufio"
	"os"
	"strconv"
)

func toInt(buf []byte) (n uint32) {
	for _, v := range buf {
		n = n*10 + uint32(v-'0')
	}
	return
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	d := bufio.NewWriter(os.Stdout)
	defer d.Flush()
	scanner.Scan()
	n := int(toInt(scanner.Bytes()))
	numbers := make([]uint32, n)
	var max uint32
	for i := 0; i < n; i++ {
		scanner.Scan()
		temp := toInt(scanner.Bytes())
		if temp > max {
			max = temp
		}
		numbers[i] = temp
	}
	counts := make([]int64, max + 1)
	for _, number := range numbers {
		counts[number]++
	}
	dp := make([]int64, max + 1)
	dp[1] = counts[1]
	for i := 2; i < int(max + 1); i++ {
		if dp[i - 1] > dp[i - 2] + (counts[i] * int64(i)) {
			dp[i] = dp[i - 1]
		}else {
			dp[i] = dp[i - 2] + (counts[i] * int64(i))
		}
	}
	d.WriteString(strconv.FormatInt(dp[max], 10))

}

package main

import (
	"bufio"
	"fmt"
	"os"
)

var N int64
var i int64
var a [100001]int64
var c [100001]int64
var l [100001]int64

func comp_l() {
	for i = 1; i <= 100000; i++ {
		l[a[i]]++
	}
}

func solve() {
	c[0] = 0
	c[1] = l[1]

	for i = 2; i <= 100000; i++ {
		// MAX
		c[i] = c[i-1]
		if c[i] < (c[i-2] + i*l[i]) {
			c[i] = c[i-2] + i*l[i]
		}
	}

	fmt.Printf("%v\n", c[100000])
}

func main() {
	input := bufio.NewReader(os.Stdin)
	// 1. read input
	fmt.Fscanf(input, "%d\n", &N)
	for i = 1; i <= N; i++ {
		fmt.Fscanf(input, "%d", &a[i])
	}
	comp_l()

	// 2. solve
	solve()

	return
}

package main

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

const maxInt = 2147483647

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	m := parse(strings.TrimSpace(text))
	// s := parse(strings.TrimSpace("2 2 3 4 5"))
	fmt.Println(getMaxPoints(m))
}

func parse(s string) map[int64]int64 {
	nn := strings.Split(s, " ")
	pm := map[int64]int64{}
	for _, n := range nn {
		v, _ := strconv.ParseInt(n, 10, 64)
		pm[v] += v
	}
	return pm
}

func getSortedMapKeys(m map[int64]int64) []int64 {
	ks := make([]int64, 0, len(m))
	for k := range m {
		ks = append(ks, k)
	}
	sort.Slice(ks, func(i, j int) bool { return ks[i] < ks[j] })
	return ks
}

func nextSmallestKeys(ks []int64, i int) (int64, int64) {
	s1, s2 := int64(0), int64(0)
	for j := i - 1; j >= 0; j-- {
		if ks[j] < ks[i]-1 {
			if s1 == 0 {
				s1 = ks[j]
			} else {
				s2 = ks[j]
				break
			}
		}
	}
	return s1, s2
}

func max(ii ...int64) int64 {
	m := int64(0)
	for _, i := range ii {
		if i > m {
			m = i
		}
	}
	return m
}

func getMaxPoints(m map[int64]int64) int64 {
	// map of int : points
	ks := getSortedMapKeys(m)

	t := map[int64]int64{} // max so far using this int
	ans := int64(0)
	for i, k := range ks {
		k1, k2 := nextSmallestKeys(ks, i)

		v := m[k]
		t[k] = v + max(t[k1], t[k2])
		ans = max(ans, t[k])
	}

	return ans
}

package main

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

const maxInt = 2147483647

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	// s := parse(strings.TrimSpace("2 2 3 4 5"))
	fmt.Println(getMaxPoints(s))
}

func parse(s string) []int64 {
	nn := strings.Split(s, " ")
	i := make([]int64, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.ParseInt(n, 10, 64)
		i = append(i, c)
	}
	return i
}

func getSortedMapKeys(m map[int64]int64) []int64 {
	ks := make([]int64, 0, len(m))
	for k := range m {
		ks = append(ks, k)
	}
	sort.Slice(ks, func(i, j int) bool { return ks[i] < ks[j] })
	return ks
}

func nextSmallestKeys(ks []int64, i int) (int64, int64) {
	s1, s2 := int64(0), int64(0)
	for j := i - 1; j >= 0; j-- {
		if ks[j] < ks[i]-1 {
			if s1 == 0 {
				s1 = ks[j]
			} else {
				s2 = ks[j]
				break
			}
		}
	}
	return s1, s2
}

func max(ii ...int64) int64 {
	m := int64(0)
	for _, i := range ii {
		if i > m {
			m = i
		}
	}
	return m
}

func maxV(mp map[int64]int64) int64 {
	m := int64(0)
	for _, v := range mp {
		if v > m {
			m = v
		}
	}
	return m
}

func getMaxPoints(s []int64) int64 {
	// map of int : points
	pm := map[int64]int64{}
	for _, v := range s {
		pm[v] += v
	}

	ks := getSortedMapKeys(pm)

	ans := map[int64]int64{} // max so far using this int
	for i, k := range ks {
		k1, k2 := nextSmallestKeys(ks, i)

		v := pm[k]
		ans[k] = v + max(ans[k1], ans[k2])
	}

	return maxV(ans)
}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO fucntions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbefferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbefferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	// SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()

	n := readi()
	a := make([]int, n)
	for i := range a {
		a[i] = readi()
	}
	c := make([]int, 100010)
	maxv := 0
	for _, v := range a {
		c[v]++
		maxv = max(maxv, v)
	}
	dp := make([]int64, len(c))
	dp[1] = int64(c[1])
	for i := 2; i <= maxv; i++ {
		dp[i] = maxll(dp[i-1], dp[i-2]+int64(i)*int64(c[i]))
	}
	println(dp[maxv])
}

package main

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

func main() {
	var elements []uint64

	reader := bufio.NewReader(os.Stdin)

	_, _ = reader.ReadString('\n')
	stringOfElements, _ := reader.ReadString('\n')

	for _, element := range strings.Fields(stringOfElements) {
		value, _ := strconv.Atoi(element)
		elements = append(elements, uint64(value))
	}

	boredomGame := NewBoredomGame(elements)
	fmt.Printf("%v", boredomGame.HighestPoint())
}

type BoredomGame struct {
	highestPoint uint64
	highestNum   uint64
	count        map[uint64]uint64
	elementSet   []uint64
	dp           map[uint64]uint64
}

func NewBoredomGame(elements []uint64) *BoredomGame {
	count, elementSet, highestNum := countElementFrequency(elements)
	boredomGame := &BoredomGame{
		count:        count,
		highestPoint: 0,
		elementSet:   elementSet,
		dp:           map[uint64]uint64{0: 0},
		highestNum:   highestNum,
	}
	return boredomGame
}

func countElementFrequency(elements []uint64) (map[uint64]uint64, []uint64, uint64) {
	result := map[uint64]uint64{}
	var set []uint64
	var highestNum uint64 = 0

	for _, element := range elements {
		frequency := result[element]
		if frequency == 0 {
			set = append(set, element)
		}
		result[element] += 1
		if element > highestNum {
			highestNum = element
		}
	}
	return result, set, highestNum
}

func (bg *BoredomGame) HighestPoint() uint64 {
	return bg.calculatePoints()
}

func (bg *BoredomGame) calculatePoints() uint64 {
	for element := uint64(1); element <= bg.highestNum; element++ {
		bg.dp[element] = Max(bg.dp[element-1], bg.dp[element-2]+(bg.count[element]*element))
		if bg.dp[element] > bg.highestPoint {
			bg.highestPoint = bg.dp[element]
		}
	}
	return bg.highestPoint
}

func Max(x, y uint64) uint64 {
	if x < y {
		return y
	}
	return x
}

// http://codeforces.com/problemset/problem/455/A
package main

import (
	"fmt"
	"bufio"
	"os"
)

// (c) Dmitriy Blokhin (sv.dblokhin@gmail.com)

const (
	MOD = 1e9 + 7
)

type (

)

func max(a, b int64 ) int64 {
	if a > b {
		return a
	}

	return b
}

func main () {
	var (
		n int
	)

	//f, _ := os.Open("input.txt")
	//input := bufio.NewReader(f)
	input := bufio.NewReader(os.Stdin)

	fmt.Fscanln(input, &n)
	m := make([]int64, 1e5 + 1)
	ma := 0
	for i := 0; i < n; i++ {
		var tmp int
		fmt.Fscan(input, &tmp)

		m[tmp]++
		if tmp > ma {
			ma = tmp
		}
	}

	f := make([]int64, ma + 1)
	f[0] = int64(0)
	f[1] = int64(m[1])

	for i := 2; i <= ma; i++ {
		f[i] = max(f[i - 1], f[i - 2] + m[i] * int64(i))
	}

	fmt.Println(f[ma])
}

package main

import (
	"bufio"
	"os"
	"strconv"
)

var (
	in  = bufio.NewScanner(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

var (
	n    int
	x    int
	maxN int = 100000
)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	read(&n)

	a := make([]int64, maxN+1)

	for i := 0; i < n; i++ {
		read(&x)
		a[x]++
	}

	dp := make([]int64, maxN+1)
	dp[1] = a[1]
	for i := 2; i <= maxN; i++ {
		dp[i] = Max(dp[i-1], a[i]*int64(i)+dp[i-2])
	}

	write(dp[maxN])
}

func Max(x, y int64) int64 {
	if x > y {
		return x
	} else {
		return y
	}
}

func write(num ...int64) {
	for _, value := range num {
		out.WriteString(strconv.FormatInt(value, 10))
		out.WriteString(" ")
	}
}

func read(num ...*int) {
	for _, value := range num {
		in.Scan()
		*value, _ = strconv.Atoi(in.Text())
	}
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"strconv"
	"time"
	"sort"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
	array []int
	dp []int64
	was []bool
	count map[int]int
)

func f(p int) int64 {
	if p == len(array) {
		return 0
	}
	if was[p] {
		return dp[p]
	}
	was[p] = true

	if p + 1 == len(array) {
		dp[p] = int64(count[array[p]]) * int64(array[p])
	} else if array[p] != array[p + 1] + 1 {
		dp[p] = int64(count[array[p]]) * int64(array[p]) + f(p + 1)
	} else {
		dp[p] = maxInt64(int64(count[array[p]]) * int64(array[p]) + f(p + 2),
			f(p + 1))
	}
	return dp[p]
}

func solve() {
	n := readInt()
	count = make(map[int]int)
	for i := 0; i < n; i++ {
		value := readInt()
		if _, ok := count[value]; !ok {
			array = append(array, value)
		}
		count[value]++
	}
	sort.Sort(sort.Reverse(sort.IntSlice(array)))
//	logln(array)
//	logln(count)
	was = make([]bool, len(array))
	dp = make([]int64, len(array))
	printInt64(f(0))
	printLine()
}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	dbg := flag.Bool("dbg", false, "Equals true, if run is in debug mode.")
	opt := flag.Bool("opt", false, "Equals true, if run is in optimized mode.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *opt || *dbg {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
		if *dbg {
			cpuprofile, _ := os.Create("/home/outside/coding/workspace/go/io/cpuprofile.txt")
			pprof.StartCPUProfile(cpuprofile)
			defer cpuprofile.Close()
			defer pprof.StopCPUProfile()
		}
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// Maximum size used to buffer a token. The actual maximum token size
	// may be smaller as the buffer may need to include, for instance, a newline.
	MaxScanTokenSize = 1 << 20
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is neded.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return 0, nil, nil
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scanf("%d\n", &n)
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	c := make([]int64, N+1)
	for sc.Scan() {
		i, err := strconv.Atoi(sc.Text())
		if err != nil {
			fmt.Println(err)
		}
		c[i] = c[i] + 1
	}
	dp := make([]int64, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+int64(i)*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

var reader *bufio.Reader

func init() {
	reader = bufio.NewReaderSize(os.Stdin, 1<<20)
}

func readInt() int {
	var t int
	var i byte
	for i, _ = reader.ReadByte(); !(i >= '0' && i <= '9'); i, _ = reader.ReadByte() {
	}

	for ; i >= '0' && i <= '9'; i, _ = reader.ReadByte() {
		t = t*10 + int(i-'0')
	}
	return t
}

func main() {
	var N int
	fmt.Fscan(reader, &N)
	fmt.Scan()

	var x int
	for i := 0; i < N; i++ {
		fmt.Fscan(reader, &x)
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

var reader *bufio.Reader

func init() {
	reader = bufio.NewReader(os.Stdin)
}

func readInt() int {
	var t int
	var i byte
	for i, _ = reader.ReadByte(); !(i >= '0' && i <= '9'); i, _ = reader.ReadByte() {
	}

	for ; i >= '0' && i <= '9'; i, _ = reader.ReadByte() {
		t = t*10 + int(i-'0')
	}
	return t
}

func main() {
	var N int
	fmt.Fscan(reader, &N)

	var x int
	for i := 0; i < N; i++ {
		fmt.Fscan(reader, &x)
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

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

const c_max = 1e5 + 1

func main() {
    var n int
    fmt.Scanf("%d\n", &n)

    bs := bufio.NewScanner(os.Stdin)
    bs.Split(bufio.ScanWords)
    nums := make([]int, c_max, c_max)
    mmax := 0
    for i := 0; i < n; i++ {
        bs.Scan()
        an, _ := strconv.Atoi(bs.Text())
        nums[an] += 1
        if mmax < an {
            mmax = an
        }
    }

    dp := make([]uint64, c_max, c_max)
    dp[1] = uint64(nums[1])

    // dp[i] = max(dp[i-1], dp[i-2] + nums[i]*i)
    for i := 2; i <= mmax; i++ {
        dp[i] = dp[i-1]
        if dp[i] < dp[i-2] + uint64(nums[i]) * uint64(i) {
            dp[i] = dp[i-2] + uint64(nums[i]) * uint64(i)
        }
    }

    fmt.Println(dp[mmax])
}

package main

import (
	"bufio"
	"strings"
	"fmt"
	"os"
	"math"
)

func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}

func readIntArray(line string) []int {

	numStrings := strings.Split(strings.TrimSpace(string(line)), " ")

	numbers := make([]int, 0)

	for _, v := range numStrings {
		var converted int

		fmt.Sscanf(v, "%d", &converted)
		numbers = append(numbers, converted)
	}

	return numbers
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	line, _ := Readln(reader)
	line, _ = Readln(reader)
	numbers := readIntArray(line)

	maxNum := uint64(0)
	for _, num := range numbers {
		if uint64(num) > uint64(maxNum) {
			maxNum = uint64(num)
		}
	}

	freq := make([]uint64, maxNum + 1)
	for _, num := range numbers {
		freq[num]++
	}

	dp := make([]uint64, maxNum + 1)
	dp[1] = freq[1]
	for i := uint64(2); i <= maxNum; i++ {
		dp[i] = uint64(math.Max(float64(dp[i - 1]), float64(dp[i - 2] + freq[i] * i)))
	}

	fmt.Println(dp[maxNum])
}

package main

// some kind of dynamic programming problems...?

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

const isDebug = true

func main() {
	var numbers int

	fmt.Scanln(&numbers)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	arrayCounter := make([]int64, 100000 + 10)
	dpCounter := make([]int64, 100000 + 10)

	for i := 0; i < numbers; i++ {
		scanner.Scan()
		v, _ := strconv.Atoi(scanner.Text())

		arrayCounter[v]++
	}

	dpCounter[0] = 0
	dpCounter[1] = arrayCounter[1]

	// take previous calculation result, and reflect it to next calculation
	for i := 2; i <= 100000; i++ {
		a := dpCounter[i-2] + arrayCounter[i] * int64(i)
		b := dpCounter[i-1]

		if a < b {
			dpCounter[i] = b
		} else {
			dpCounter[i] = a
		}
	}

	fmt.Println(dpCounter[100000])
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func max(x, y int64) int64 {
	if y > x {
		return y
	} else {
		return x
	}
}

var data [100001]int64
var ans [100001]int64

func main() {
	var n, m int64

	reader := bufio.NewReaderSize(os.Stdin, 40960)

	fmt.Fscanf(reader, "%d\n", &n)
	for i := int64(0); i < n; i++ {
		fmt.Fscanf(reader, "%d", &m)
		data[m]++
	}

	ans[1] = data[1]

	m = ans[1]
	for i := int64(2); i < 100001; i++ {
		//ans[i] = max(ans[i-1], ans[i-2]+data[i]*i)
		if ans[i-1] < ans[i-2]+i*data[i] {
			ans[i] = ans[i-2] + i*data[i]
		} else {
			ans[i] = ans[i-1]
		}

		if ans[i] > m {
			m = ans[i]
		}
	}

	fmt.Printf("%d\n", m)
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func max(x, y int64) int64 {
	if y > x {
		return y
	} else {
		return x
	}
}

var data [100001]int64
var ans [100001]int64

func main() {
	var n, m int64

	reader := bufio.NewReader(os.Stdin)

	fmt.Fscanf(reader, "%d\n", &n)
	for i := int64(0); i < n; i++ {
		fmt.Fscanf(reader, "%d", &m)
		data[m]++
	}

	ans[1] = data[1]

	m = ans[1]
	for i := int64(2); i < 100001; i++ {
		//ans[i] = max(ans[i-1], ans[i-2]+data[i]*i)
		if ans[i-1] < ans[i-2]+i*data[i] {
			ans[i] = ans[i-2] + i*data[i]
		} else {
			ans[i] = ans[i-1]
		}

		if ans[i] > m {
			m = ans[i]
		}
	}

	fmt.Printf("%d\n", m)
}

package main;

import (
	"fmt"
	"os"
	"bufio"
)

var i int64
var dp [100001]int64
var a [100001]int64
var l [100001]int64

func compute_l(){
	for i=1;i<=100000;i++ {
		l[a[i]]++
	}
}

func do() {
	dp[0] = 0
	dp[1] = l[1]

	for i=2;i<=100000;i++ {
		dp[i] = dp[i-1]
		if dp[i] < l[i]*i+dp[i-2] {
			dp[i] = l[i]*i+dp[i-2]
			// fmt.Println(dp[i])
		}
	}

	fmt.Printf("%v\n", dp[100000])
}

func main() {
	var n int64
	input := bufio.NewReader(os.Stdin)
	fmt.Fscanf(input, "%d\n", &n)
	for i=1;i<=n;i++ {
		fmt.Fscanf(input, "%d", &a[i])
	}
	compute_l()
	do()
}

package main

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

var in *bufio.Scanner = bufio.NewScanner(os.Stdin)
var out *bufio.Writer = bufio.NewWriter(os.Stdout)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	const lim = 100100
	n, a, dp := nextInt(), make([]int64, lim), make([]int64, lim)
	for i := 0; i < n; i++ {
		a[nextInt()]++
	}
	dp[1] = a[1]
	for i := 2; i < lim; i++ {
		dp[i] = max(dp[i-1], dp[i-2] + a[i] * int64(i))
	}
	fmt.Println(dp[lim-1])
}

func max(x, y int64) int64 {
	if x > y {
		return x
	}
	return y
}

func nextInt() int {
	in.Scan()
	res, _ := strconv.Atoi(in.Text())
	return res
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

var reader *bufio.Reader

func init() {
	reader = bufio.NewReaderSize(os.Stdin, 8192)
}

func readInt() int {
	var t int
	var i byte
	for i, _ = reader.ReadByte(); !(i >= '0' && i <= '9'); i, _ = reader.ReadByte() {
	}

	for ; i >= '0' && i <= '9'; i, _ = reader.ReadByte() {
		t = t*10 + int(i-'0')
	}
	return t
}

func main() {
	var N int
	fmt.Fscan(reader, &N)
	fmt.Scan()

	var x int
	for i := 0; i < N; i++ {
		fmt.Fscan(reader, &x)
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

var reader *bufio.Reader

func init() {
	reader = bufio.NewReader(os.Stdin)
}

func readInt() int {
	var t int
	var i byte
	for i, _ = reader.ReadByte(); !(i >= '0' && i <= '9'); i, _ = reader.ReadByte() {
	}

	for ; i >= '0' && i <= '9'; i, _ = reader.ReadByte() {
		t = t*10 + int(i-'0')
	}
	return t
}

func main() {
	var N int = readInt()

	var x int
	for i := 0; i < N; i++ {
		x = readInt()
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import (
	"fmt"
	"bufio"
	"os"
)

const maxValue = 100007

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func main()  {
	var n int
	inBuf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(inBuf,"%d\n", &n)

	values := make([]int64, maxValue)

	format := "%d"
	for i := 0; i < n; i++ {
		var tmp int64
		fmt.Fscanf(inBuf, format, &tmp)
		values[tmp] += tmp
		format = " %d"
	}

	dp := make([][]int64, 2)
	dp[0] = make([]int64, maxValue)
	dp[1] = make([]int64, maxValue)

	for i := 2; i < maxValue; i++ {
		dp[0][i] = dp[1][i-1] + values[i-1]
		dp[1][i] = max(dp[0][i-1], dp[1][i-1])
	}

	//fmt.Println(dp[0][:10])
	//fmt.Println(dp[1][:10])

	fmt.Println(max(dp[0][maxValue-1], dp[1][maxValue-1]))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

const maxLen = 100001

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte, n int) []int {
	intStart := 0
	ans := make([]int, 0, n)
	for intStart < len(a) {
		ans = append(ans, parseInt(a, intStart))
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

func calcCounts(a []int) [maxLen]int {
	ans := [maxLen]int{}
	for _, v := range a {
		ans[v] += 1
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Порядок чисел в последовательности ничего не значит. Плюс лимиты на возможные значения не высокие,
// поэтому нам достаточно подсчитать кол-во одинаковых чисел и проитерироваться через весь промежуток
// возможных значений на предмет эффективности удаления i (итерируемого) из последовательности
func taskSolution(in []byte, n int) int64 {
	a := parseInput(in, n)
	counts := calcCounts(a)

	f2, f1 := int64(0), int64(0)
	for i := 0; i < maxLen; i += 1 {
		f2, f1 = f1, max(f1, f2+int64(i)*int64(counts[i]))
	}
	return f1
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw), n))
}

// Author: sighduck
// URL: https://codeforces.com/problemset/problem/455/A

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MaxElem = 100000

func max(x int64, y int64) int64 {
	if x > y {
		return x
	}
	return y
}

func Solve(n int, a []int64) int64 {
	count := make([]int64, MaxElem+1)
	for _, elem := range a {
		count[elem] += 1
	}
	dp := make([]int64, MaxElem+1)
	dp[1] = count[1]
	for i := int64(2); i <= MaxElem; i++ {
		dp[i] = max(dp[i-1], dp[i-2]+count[i]*i)
	}
	return dp[MaxElem]
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n int
	fmt.Fscanf(reader, "%d\n", &n)
	a := make([]int64, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%d ", &a[i])
	}

	fmt.Fprintf(writer, "%d\n", Solve(n, a))
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	const maximum = 100010
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	length := toInt64(scanner.Bytes())

	var values [maximum]int64
	for i := int64(0); i < length; i++ {
		scanner.Scan()
		values[toInt64(scanner.Bytes())]++
	}

	var dp [maximum][2] int64
	dp[1][0] = 0
	dp[1][1] = values[1]
	for i := int64(2); i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + values[i]*i
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

func toInt64(buf []byte) (n int64) {
	for _, v := range buf {
		n = n*10 + int64(v-'0')
	}
	return
}

package main

import (
	"bufio"
	"strings"
	"fmt"
	"os"
	"math"
)

func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}

func readIntArray(line string) []int {

	numStrings := strings.Split(strings.TrimSpace(string(line)), " ")

	numbers := make([]int, 0)

	for _, v := range numStrings {
		var converted int

		fmt.Sscanf(v, "%d", &converted)
		numbers = append(numbers, converted)
	}

	return numbers
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	line, _ := Readln(reader)
	line, _ = Readln(reader)
	numbers := readIntArray(line)

	maxNum := 0
	for _, num := range numbers {
		if num > maxNum {
			maxNum = num
		}
	}

	freq := make([]int, maxNum + 1)
	for _, num := range numbers {
		freq[num]++
	}

	dp := make([]int, maxNum + 1)
	dp[1] = freq[1]
	for i := 2; i <= maxNum; i++ {
		dp[i] = int(math.Max(float64(dp[i - 1]), float64(dp[i - 2] + freq[i] * i)))
	}

	fmt.Println(dp[maxNum])
}

package main

import (
	"bufio"
	"strings"
	"fmt"
	"os"
)

func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}

func readIntArray(line string) []int {

	numStrings := strings.Split(strings.TrimSpace(string(line)), " ")

	numbers := make([]int, 0)

	for _, v := range numStrings {
		var converted int

		fmt.Sscanf(v, "%d", &converted)
		numbers = append(numbers, converted)
	}

	return numbers
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	line, _ := Readln(reader)
	line, _ = Readln(reader)
	numbers := readIntArray(line)

	fmt.Println(GetMaxScore(numbers[:], 0))
}

func GetMaxScore(numbers []int, currentScore int) int {
	if len(numbers) == 0 {
		return currentScore
	}

	if len(numbers) == 1 {
		return currentScore + numbers[0]
	}

	maxScore := 0
	for idx := range numbers {

		var newRange []int
		if len(numbers) == 2 {
			newRange = []int{}
		} else {
			if idx == 0 {
				newRange = numbers[2:]
			} else if idx == len(numbers) - 1 {
				newRange = numbers[:idx - 1]
			} else {
				newRange = append([]int{}, numbers[:idx - 1]...)
				newRange = append(newRange, numbers[idx + 2:]...)
			}
		}

		newScore := GetMaxScore(newRange, currentScore + numbers[idx])
		if newScore > maxScore {
			maxScore = newScore
		}
	}

	return maxScore
}

package main

import (
	"bufio"
	"strings"
	"fmt"
	"os"
)

func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}

func readIntArray(line string) []int {

	numStrings := strings.Split(strings.TrimSpace(string(line)), " ")

	numbers := make([]int, 0)

	for _, v := range numStrings {
		var converted int

		fmt.Sscanf(v, "%d", &converted)
		numbers = append(numbers, converted)
	}

	return numbers
}

func main() {
	var count int
	fmt.Scanf("%d\n", &count)

	reader := bufio.NewReader(os.Stdin)
	line, _ := Readln(reader)
	numbers := readIntArray(line)

	fmt.Println(GetMaxScore(numbers, 0))
}

func GetMaxScore(numbers []int, currentScore int) int {
	if len(numbers) == 0 {
		return currentScore
	}

	if len(numbers) == 1 {
		return currentScore + numbers[0]
	}

	maxScore := 0
	for idx := range numbers {

		var newRange []int
		if len(numbers) == 2 {
			newRange = []int{}
		} else {
			if idx == 0 {
				newRange = numbers[2:]
			} else if idx == len(numbers) - 1 {
				newRange = numbers[:idx - 1]
			} else {
				newRange = append(numbers[:idx - 1], numbers[idx + 2:]...)
			}
		}

		newScore := GetMaxScore(newRange, currentScore + numbers[idx])
		if newScore > maxScore {
			maxScore = newScore
		}
	}

	return maxScore
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func max(x, y int) int {
	if y > x {
		return y
	} else {
		return x
	}
}

var data [100001]int
var ans [100001]int

func main() {
	var n, m int

	reader := bufio.NewReader(os.Stdin)

	fmt.Fscanf(reader, "%d\n", &n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%d", &m)
		data[m]++
	}

	ans[1] = data[1]

	m = ans[1]
	for i := 2; i < 100001; i++ {
		//ans[i] = max(ans[i-1], ans[i-2]+data[i]*i)
		if ans[i-1] < ans[i-2]+i*data[i] {
			ans[i] = ans[i-2] + i*data[i]
		} else {
			ans[i] = ans[i-1]
		}

		if ans[i] > m {
			m = ans[i]
		}
	}

	fmt.Printf("%d\n", m)
}

package main;

import (
	"fmt"
	"os"
	"bufio"
)

var N int64
var i int64
var dp [100001]int64
var a [100001]int64
var l [100001]int64

func compute_l(){
	for i=1;i<=100000;i++ {
		l[a[i]]++
	}
}

func do() {
	dp[0] = 0
	dp[1] = l[1]

	for i=2;i<=100000;i++ {
		dp[i] = dp[i-1]
		if dp[i] < l[i]*i+dp[i-2] {
			dp[i] = l[i]*i+dp[i-2]
			// fmt.Println(dp[i])
		}
	}

	fmt.Printf("%v\n", dp[100000])
}

func main() {
	var n int64
	input := bufio.NewReader(os.Stdin)
	fmt.Scan(&n)
	for i=1;i<=n;i++ {
		fmt.Fscanf(input, "%d", &a[i])
	}
	compute_l()
	do()
}

package main;

import "fmt"

var N int64
var i int64
var dp [100001]int64
var a [100001]int64
var l [100001]int64

func compute_l(){
	for i=1;i<=100000;i++ {
		l[a[i]]++
	}
}

func do() int64 {
	dp[0] = 0
	dp[1] = l[1]

	for i=2;i<=100000;i++ {
		dp[i] = dp[i-1]
		if dp[i] < l[i]*i+dp[i-2] {
			dp[i] = l[i]*i+dp[i-2]
		}
	}

	return dp[100000]
}

func main() {
	var n int64
	fmt.Scan(&n)
	for i=0;i<n;i++ {
		fmt.Scan(&a[i])
	}
	compute_l()
	fmt.Println(do())
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

const (
	MinUint uint = 0
	MaxUint      = ^MinUint
	MaxInt       = int(MaxUint >> 1)
	MinInt       = ^MaxInt
)

type pair struct {
	count int
	point int
}
type sequence map[int]pair

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte) sequence {
	intStart := 0
	ans := sequence{}
	for intStart < len(a) {
		parsed := parseInt(a, intStart)
		ans[parsed] = pair{count: ans[parsed].count + 1, point: 0}
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Задача на динамическое программирование, т.е. на "перебор с оптимизациями".
// Оптимизация сводиться к структуризации входного потока и удаления элементов пачками.
// Структурированные данные можно прогонять рекурсивно как map[int]int или как массив
// на 100000 элементов (ограничение сверху из условия)
func taskSolution(a []byte) (ans int) {
	parsed := parseInput(a)
	// calc init points
	for i, v := range parsed {
		if left, ok := parsed[i-1]; ok {
			parsed[i-1] = pair{
				count: left.count,
				point: left.point - i*v.count,
			}
		}
		parsed[i] = pair{
			count: v.count,
			point: v.point + i*v.count,
		}
		if right, ok := parsed[i+1]; ok {
			parsed[i+1] = pair{
				count: right.count,
				point: right.point - i*v.count,
			}
		}
	}
	// iterate
	for len(parsed) > 0 {
		maxi, maxv := 0, MinInt
		// find maxed value
		for i, v := range parsed {
			if maxv < v.point {
				maxi = i
				maxv = v.point
			}
		}
		// calc
		ans += maxi * parsed[maxi].count
		// remove it
		if leftleft, ok := parsed[maxi-2]; ok {
			parsed[maxi-2] = pair{
				count: leftleft.count,
				point: leftleft.point + (maxi-1)*parsed[maxi-1].point,
			}
		}
		if rightright, ok := parsed[maxi+2]; ok {
			parsed[maxi+2] = pair{
				count: rightright.count,
				point: rightright.point + (maxi+1)*parsed[maxi+1].point,
			}
		}
		delete(parsed, maxi-1)
		delete(parsed, maxi)
		delete(parsed, maxi+1)
	}
	return ans
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte) []int {
	intStart := 0
	ans := []int{}
	for intStart < len(a) {
		ans = append(ans, parseInt(a, intStart))
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

func calcCounts(a []int) map[int]int {
	ans := map[int]int{}
	for _, v := range a {
		ans[v] += 1
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Я честно списал решение из ответов, потому что все реализуемые мной переборы
// были неэффективны по времени. К списанному решению у меня есть как минимум одна претензия:
// для input:
// 2
// 1 10
// он отдаёт ответ 1, хотя правильно 10 (читаем условие - 1<=ai<=10^5 , а не 1<=ai<=n как предполагается)
func taskSolution(in []byte) (ans int) {
	a := parseInput(in)
	counts := calcCounts(a)

	f2, f1 := 0, 0
	for i := 0; i <= len(a); i += 1 {
		f2, f1 = f1, max(f1, f2+i*counts[i])
	}
	return f1
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte) []int {
	intStart := 0
	ans := []int{}
	for intStart < len(a) {
		ans = append(ans, parseInt(a, intStart))
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

func calcCounts(a []int) map[int]int {
	ans := map[int]int{}
	for _, v := range a {
		ans[v] += 1
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Я честно списал решение из ответов, потому что все реализуемые мной переборы
// были неэффективны по времени. К списанному решению у меня есть как минимум одна претензия:
// для input:
// 2
// 1 10
// он отдаёт ответ 1, хотя правильно 10 (читаем условие - 1<=ai<=10^5 , а не 1<=ai<=n как предполагается)
func taskSolution(in []byte) int64 {
	a := parseInput(in)
	counts := calcCounts(a)

	f2, f1 := int64(0), int64(0)
	for i := 0; i <= len(a); i += 1 {
		f2, f1 = f1, max(f1, f2+int64(i)*int64(counts[i]))
	}
	return f1
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte) []int {
	intStart := 0
	ans := []int{}
	for intStart < len(a) {
		ans = append(ans, parseInt(a, intStart))
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

func calcCounts(a []int) map[int]int {
	ans := map[int]int{}
	for _, v := range a {
		ans[v] += 1
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Я честно списал решение из ответов, потому что все реализуемые мной переборы
// были неэффективны по времени. К списанному решению у меня есть как минимум одна претензия:
// для input:
// 2
// 1 10
// он отдаёт ответ 1, хотя правильно 10 (читаем условие - 1<=ai<=10^5 , а не 1<=ai<=n как предполагается)
func taskSolution(in []byte) int64 {
	a := parseInput(in)
	counts := calcCounts(a)

	f2, f1 := int64(0), int64(0)
	for i := 0; i <= len(a); i += 1 {
		f2, f1 = f1, max(f1, f2+int64(i*counts[i]))
	}
	return f1
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
)

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

func parseInput(a []byte) map[int]int {
	intStart := 0
	ans := map[int]int{}
	for intStart < len(a) {
		ans[parseInt(a, intStart)] += 1
		// skip iterated
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
func taskSolution(a []byte) (ans int) {
	parsed := parseInput(a)
	for len(parsed) > 0 {
		// find max
		maxNum := 0
		count := 0
		for i, v := range parsed {
			if v > count {
				maxNum = i
				count = v
			} else if v == count {
				if i > maxNum {
					maxNum = i
					count = v
				}
			}
		}
		ans += maxNum * count
		if _, ok := parsed[maxNum-1]; ok {
			delete(parsed, maxNum-1)
		}
		delete(parsed, maxNum)
		if _, ok := parsed[maxNum+1]; ok {
			delete(parsed, maxNum+1)
		}
	}
	return ans
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"sort"
)

type sequence map[int]int

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

// parse positive int from byte slice
func parseInt(a []byte, start int) (ans int) {
	for i := start; i < len(a) && a[i] >= '0' && a[i] <= '9'; i += 1 {
		// skip overflow check
		ans = 10*ans + int(a[i]-'0')
	}
	return ans
}

// parse byte slice (string) into structurized array/map; faster then fmt.Scan
func parseInput(a []byte) sequence {
	intStart := 0
	ans := sequence{}
	for intStart < len(a) {
		ans[parseInt(a, intStart)] += 1
		// find next
		for intStart < len(a) && a[intStart] >= '0' && a[intStart] <= '9' {
			intStart += 1
		}
		for intStart < len(a) && !(a[intStart] >= '0' && a[intStart] <= '9') {
			intStart += 1
		}
	}
	return ans
}

// https://codeforces.com/problemset/problem/455/A
// комментарии к решению
// Задача на динамическое программирование, т.е. на "перебор с оптимизациями".
// Оптимизация сводиться к структуризации входного потока и удаления элементов пачками.
// Структурированные данные можно прогонять рекурсивно как map[int]int или как массив
// на 100000 элементов (ограничение сверху из условия)
func taskSolution(a []byte) (ans int) {
	parsed := parseInput(a)

	keys := make([]int, 0, len(parsed))
	for k, _ := range parsed {
		keys = append(keys, k)
	}
	sort.Ints(keys)

	f2 := 0
	f1 := keys[0] * parsed[keys[0]]
	for i := 1; i < len(keys); i += 1 {
		f2, f1 = f1, max(f1, f2+parsed[keys[i]]*keys[i])
	}
	return f1
}

func main() {
	var n int
	if _, err := fmt.Scan(&n); err != nil {
		panic(err)
	}

	inRaw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	fmt.Println(taskSolution(bytes.TrimSpace(inRaw)))
}

package main

import (
	"fmt"
)

func main() {
	const maximum = 100010
	var length int
	_,_ = fmt.Scanf("%d", &length)

	var numbers []int
	var values [maximum]int
	for i := 0; i < length; i++ {
		var curNum int
		_,_ = fmt.Scanf("%d", &curNum)

		numbers = append(numbers, curNum)
		values[curNum]++
	}

	var dp [maximum][2]int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

package main

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

func main() {
	const maximum = 100010
	s := bufio.NewScanner(os.Stdin)
	s.Scan()
	s.Scan()
	splits := strings.Split(s.Text(), " ")

	var values [maximum]int
	for i := 0; i < len(splits); i++ {
		curNum, _ := strconv.Atoi(splits[i])
		values[curNum]++
	}

	var dp [maximum][2]int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	const maximum = 100001
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	length := toInt(scanner.Bytes())

	var values [maximum]int
	for i := 0; i < length; i++ {
		scanner.Scan()
		values[toInt(scanner.Bytes())]++
	}

	var dp [maximum][2]int
	dp[1][0] = 0
	dp[1][1] = values[1]
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + values[i] * i
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int) int {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

func toInt(buf []byte) (n int) {
	for _, v := range buf {
		n = n*10 + int(v-'0')
	}
	return
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	const maximum = 100010
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	length := toInt(scanner.Bytes())

	var values [maximum]int
	for i := 0; i < length; i++ {
		scanner.Scan()
		values[toInt(scanner.Bytes())]++
	}

	var dp [maximum][2] int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

func toInt(buf []byte) (n int) {
	for _, v := range buf {
		n = n*10 + int(v-'0')
	}
	return
}

package main

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

func main() {
	const maximum = 100010
	s := bufio.NewScanner(os.Stdin)
	s.Scan()
	length, _ := strconv.Atoi(s.Text())

	var numbers []int
	var values [maximum]int
	for i := 0; i < length; i++ {
		s.Scan()
		curNum, _ := strconv.Atoi(s.Text())

		numbers = append(numbers, curNum)
		values[curNum]++
	}

	var dp [maximum][2]int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

package main

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

func main() {
	const maximum = 100010
	reader := bufio.NewReader(os.Stdin)
	text, _ := reader.ReadString('\n')
	text, _ = reader.ReadString('\n')
	text = strings.Replace(text, "\n", "", -1)
	splits := strings.Split(text, " ")

	var values [maximum]int
	for i := 0; i < len(splits); i++ {
		curNum, _ := strconv.Atoi(splits[i])
		values[curNum]++
	}

	var dp [maximum][2]int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	const maximum = 100001
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	length := toInt(scanner.Bytes())

	var values [maximum]int
	for i := 0; i < length; i++ {
		scanner.Scan()
		values[toInt(scanner.Bytes())]++
	}

	var dp [maximum][2] int64
	dp[1][0] = 0
	dp[1][1] = int64(values[1])
	for i := 2; i < maximum; i++ {
		dp[i][0] = Max(dp[i-1][0], dp[i-1][1])
		dp[i][1] = dp[i-1][0] + int64(values[i] * i)
	}

	fmt.Println(Max(dp[maximum-1][0], dp[maximum - 1][1]))
}

func Max(lhs, rhs int64) int64 {
	if lhs < rhs {
		return rhs
	}

	return lhs
}

func toInt(buf []byte) (n int) {
	for _, v := range buf {
		n = n*10 + int(v-'0')
	}
	return
}

package main

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

var in *bufio.Scanner = bufio.NewScanner(os.Stdin)
var out *bufio.Writer = bufio.NewWriter(os.Stdout)

var memo = make([]int, 100100)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	n, m := nextInt(), make(map[int]int)
	for i := 0; i < n; i++ {
		m[nextInt()]++
	}
	keys := make([]int, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	sort.Ints(keys)
	fmt.Println(max(rec(m, keys, 0), rec(m, keys, 1)))
}

func rec(a map[int]int, keys []int, i int) int {
	if i >= len(keys) {
		return 0
	}
	if memo[i] != 0 {
		return memo[i]
	}
	memo[i] = a[keys[i]] * keys[i]
	if i + 1 == len(keys) {
		return memo[i]
	}
	if keys[i + 1] - keys[i] == 1 {
		memo[i] += rec(a, keys, i + 2)
	} else {
		memo[i] += rec(a, keys, i + 1)
	}
	return memo[i]
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func nextInt() int {
	in.Scan()
	res, _ := strconv.Atoi(in.Text())
	return res
}

package main

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

var in *bufio.Scanner = bufio.NewScanner(os.Stdin)
var out *bufio.Writer = bufio.NewWriter(os.Stdout)

var memo = make([]int, 100100)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	n, m := nextInt(), make(map[int]int)
	for i := 0; i < n; i++ {
		m[nextInt()]++
	}
	keys := make([]int, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	sort.Ints(keys)
	fmt.Println(rec(m, keys, 0))
}

func rec(a map[int]int, keys []int, i int) int {
	if i >= len(keys) {
		return 0
	}
	if memo[i] != 0 {
		return memo[i]
	}
	memo[i] = a[keys[i]] * keys[i]
	if i + 1 == len(keys) {
		return memo[i]
	}
	if keys[i + 1] - keys[i] == 1 {
		memo[i] = max(memo[i] + rec(a, keys, i + 2), rec(a, keys, i + 1))
	} else {
		memo[i] += rec(a, keys, i + 1)
	}
	return memo[i]
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func nextInt() int {
	in.Scan()
	res, _ := strconv.Atoi(in.Text())
	return res
}

package main

import (
	"bufio"
	"os"
	"strconv"
)

func toInt(buf []byte) (n int) {
	for _, v := range buf {
		n = n*10 + int(v-'0')
	}
	return
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	d := bufio.NewWriter(os.Stdout)
	defer d.Flush()
	scanner.Scan()
	n := toInt(scanner.Bytes())
	numbers := make([]int, n)
	var max int
	for i := 0; i < n; i++ {
		scanner.Scan()
		temp := toInt(scanner.Bytes())
		if temp > max {
			max = temp
		}
		numbers[i] = temp
	}
	counts := make([]int, max + 1)
	for _, number := range numbers {
		counts[number]++
	}
	dp := make([]int, max + 1)
	dp[1] = counts[1]
	for i := 2; i < max + 1; i++ {
		if dp[i - 1] > dp[i - 2] + (counts[i] * i) {
			dp[i] = dp[i - 1]
		}else {
			dp[i] = dp[i - 2] + (counts[i] * i)
		}
	}
	d.WriteString(strconv.Itoa(dp[max]))

}

package main

import (
	"bufio"
	"os"
	"strconv"
)

func toInt(buf []byte) (n uint32) {
	for _, v := range buf {
		n = n*10 + uint32(v-'0')
	}
	return
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	d := bufio.NewWriter(os.Stdout)
	defer d.Flush()
	scanner.Scan()
	n := int(toInt(scanner.Bytes()))
	numbers := make([]uint32, n)
	var max uint32
	for i := 0; i < n; i++ {
		scanner.Scan()
		temp := toInt(scanner.Bytes())
		if temp > max {
			max = temp
		}
		numbers[i] = temp
	}
	counts := make([]uint32, max + 1)
	for _, number := range numbers {
		counts[number]++
	}
	dp := make([]uint32, max + 1)
	dp[1] = counts[1]
	for i := 2; i < int(max + 1); i++ {
		if dp[i - 1] > dp[i - 2] + (counts[i] * uint32(i)) {
			dp[i] = dp[i - 1]
		}else {
			dp[i] = dp[i - 2] + (counts[i] * uint32(i))
		}
	}
	d.WriteString(strconv.FormatInt(int64(dp[max]), 10))

}

package main

import (
	"fmt"
	"bufio"
	"os"
)

const maxValue = 100007

func main()  {
	var n int
	inBuf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(inBuf,"%d\n", &n)

	values := make([]int64, maxValue)

	format := "%d"
	for i := 0; i < n; i++ {
		var tmp int64
		fmt.Fscanf(inBuf, format, &tmp)
		values[tmp] += tmp
		format = " %d"
	}

	dp := make([][]int64, 2)
	dp[0] = make([]int64, maxValue)
	dp[1] = make([]int64, maxValue)

	for i := 1; i < maxValue; i++ {
		dp[0][i] = dp[1][i-1] + values[i-1]
		dp[1][i] = dp[0][i-1]
	}

	m1 := dp[0][maxValue-1]
	m2 := dp[1][maxValue-1]

	if m1 > m2 {
		fmt.Println(m1)
	} else {
		fmt.Println(m2)
	}

}

package main

import (
	"fmt"
	"math"
)

var N int;
var a [100001] int;
var c [100001] int;

func solve(){
	c[0] = 0;
	c[1] = a[1];
	c[2] = a[1];
	if c[2] < a[2] { c[2] = a[2]; }

	for i:=3; i<=N; i++ {
		c[i] = int(math.Max(float64(c[i-2] + a[i]), float64(a[i-1] + c[i-3])));
	}

	fmt.Printf("%d\n", (c[N]));
}

func main() {
	// 1. read input
	fmt.Scan(&N);
	for i:=1 ; i<=N; i++ {
		fmt.Scan(&a[i]);
	}
	// 2. solve
	solve();

	return;
}

// c[i] = max value from 1 to i-th.
// c[i] = max ( c[i-2] + a[i] , a[i-1] + c[i-3] )

package main

import (
	"bufio"
	"fmt"
	"os"
)

var N int64
var i int64
var a [100001]int64
var c [100001]int64
var l [100001]int64

func comp_l() {
	for i = 0; i <= 100000; i++ {
		l[a[i]]++
	}
}

func solve() {
	c[0] = 0
	c[1] = l[1]

	for i = 2; i <= N; i++ {
		c[i] = c[i-1]
		if c[i] < (c[i-2] + i*l[i]) {
			c[i] = c[i-2] + i*l[i]
		}
	}

	fmt.Printf("%v\n", (c[N]))
}

func main() {
	input := bufio.NewReader(os.Stdin)
	// 1. read input
	fmt.Fscanf(input, "%d\n", &N)
	//fmt.Printf("%d\n", N)
	for i = 1; i <= N; i++ {
		fmt.Fscanf(input, "%d", &a[i])
		//fmt.Printf("%d ", a[i])
	}
	comp_l()

	// 2. solve
	solve()

	return
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

var N int64
var i int64
var a [100001]int64
var c [100001]int64
var l [100001]int64

func comp_l() {
	for i = 0; i <= 100000; i++ {
		l[a[i]]++
	}
}

func solve() {
	c[0] = 0
	c[1] = l[1]

	for i = 2; i <= N; i++ {
		c[i] = c[i-1]
		if c[i] < (c[i-2] + i*l[i]) {
			c[i] = c[i-2] + i*l[i]
		}
	}

	fmt.Printf("%d\n", (c[N]))
}

func main() {
	input := bufio.NewReader(os.Stdin)
	// 1. read input
	fmt.Fscanf(input, "%d\n", &N)
	//fmt.Printf("%d\n", N)
	for i = 1; i <= N; i++ {
		fmt.Fscanf(input, "%d", &a[i])
		//fmt.Printf("%d ", a[i])
	}
	comp_l()

	// 2. solve
	solve()

	return
}

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	// s := parse(strings.TrimSpace("10 5 8 9 5 6 8 7 2 8"))
	fmt.Println(getMaxPoints(s))
}

func sum(a int, b int) int {
	return a + b
}

func parse(s string) []int {
	nn := strings.Split(s, " ")
	i := make([]int, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.Atoi(n)
		i = append(i, c)
	}
	return i
}

func getSortedMapKeys(m map[int]int) []int {
	ks := make([]int, 0, len(m))
	for k := range m {
		ks = append(ks, k)
	}
	sort.Ints(ks)
	return ks
}

func nextSmallestKeys(ks []int, i int) (int, int) {
	s1, s2 := 0, 0
	for j := i - 1; j >= 0; j-- {
		if ks[j] < ks[i]-1 {
			if s1 == 0 {
				s1 = ks[j]
			} else {
				s2 = ks[j]
				break
			}
		}
	}
	return s1, s2
}

func max(ii ...int) int {
	m := 0
	for _, i := range ii {
		if i > m {
			m = i
		}
	}
	return m
}

func maxV(mp map[int]int) int {
	m := 0
	for _, v := range mp {
		if v > m {
			m = v
		}
	}
	return m
}

func getMaxPoints(s []int) int {
	// map of int : points
	pm := map[int]int{}
	for _, v := range s {
		pm[v] += v
	}

	ks := getSortedMapKeys(pm)

	ans := map[int]int{} // max so far using this int
	for i, k := range ks {
		k1, k2 := nextSmallestKeys(ks, i)

		v := pm[k]
		ans[k] = max(v, v+max(ans[k1], ans[k2]))
	}

	return maxV(ans)
}

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	fmt.Println(getMaxPoints(s))
}

func parse(s string) []int {
	nn := strings.Split(s, " ")
	i := make([]int, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.Atoi(n)
		i = append(i, c)
	}
	return i
}

func splitBlocks(s []int) [][]int {
	bb := [][]int{}

	i := 0
	for i < len(s) {
		prev := s[i]
		b := []int{s[i]}

		j := i+1
		for j < len(s) {
			if s[j] <= prev+2 {
				b = append(b, s[j])
				prev = s[j]
				j++
			} else {
				break
			}
		}

		bb = append(bb, b)
		i=j
	}

	return bb
}

func getMaxPoints(s []int) int {
	sort.Ints(s)
	bb := splitBlocks(s)
	p := 0
	for _, b := range bb {
		odd, even := 0, 0
		for _, i := range b {
			if i%2 == 0 {
				even += i
			} else {
				odd += i
			}
		}
		if odd > even {
			p += odd
		} else {
			p += even
		}
	}
	return p
}

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	fmt.Println(getMaxPoints(s)) // fmt.Println(getMaxPoints(parse("5 3 5 3 4")))
}

func parse(s string) []int {
	nn := strings.Split(s, " ")
	i := make([]int, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.Atoi(n)
		i = append(i, c)
	}
	return i
}

func getSortedMapKeys(m map[int]int) []int {
	ks := make([]int, 0, len(m))
	for k := range m {
		ks = append(ks, k)
	}
	sort.Ints(ks)
	return ks
}
func nextSmallestKeys(ks []int, i int) (int, int) {
	s1, s2 := 0, 0
	for j := i - 1; j >= 0; j-- {
		if ks[j] < ks[i]-1 {
			if s2 == 0 {
				s1 = ks[j]
			} else {
				s2 = ks[j]
				break
			}
		}
	}
	return s1, s2
}

func max(ii ...int) int {
	m := 0
	for _, i := range ii {
		if i > m {
			m = i
		}
	}
	return m
}

func getMaxPoints(s []int) int {
	// map of int : points
	pm := map[int]int{}
	for _, v := range s {
		pm[v] += v
	}

	ks := getSortedMapKeys(pm)

	ans := map[int]int{} // max so far using this int
	for i, k := range ks {
		k1, k2 := nextSmallestKeys(ks, i)
		v := pm[k]
		ans[k] = v + max(ans[k1], ans[k2])
	}

	return max(ans[ks[len(ks)-1]], ans[ks[len(ks)-2]])
}

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	// s := parse(strings.TrimSpace("10 5 8 9 5 6 8 7 2 8"))
	fmt.Println(getMaxPoints(s))
}

func parse(s string) []int {
	nn := strings.Split(s, " ")
	i := make([]int, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.Atoi(n)
		i = append(i, c)
	}
	return i
}

func getSortedMapKeys(m map[int]int) []int {
	ks := make([]int, 0, len(m))
	for k := range m {
		ks = append(ks, k)
	}
	sort.Ints(ks)
	return ks
}

func nextSmallestKeys(ks []int, i int) (int, int) {
	s1, s2 := 0, 0
	for j := i - 1; j >= 0; j-- {
		if ks[j] < ks[i]-1 {
			if s1 == 0 {
				s1 = ks[j]
			} else {
				s2 = ks[j]
				break
			}
		}
	}
	return s1, s2
}

func max(ii ...int) int {
	m := 0
	for _, i := range ii {
		if i > m {
			m = i
		}
	}
	return m
}

func maxV(mp map[int]int) int {
	m := 0
	for _, v := range mp {
		if v > m {
			m = v
		}
	}
	return m
}

func getMaxPoints(s []int) int {
	// map of int : points
	pm := map[int]int{}
	for _, v := range s {
		pm[v] += v
	}

	ks := getSortedMapKeys(pm)

	ans := map[int]int{} // max so far using this int
	for i, k := range ks {
		k1, k2 := nextSmallestKeys(ks, i)

		v := pm[k]
		ans[k] = v + max(ans[k1], ans[k2])
	}

	return maxV(ans)
}

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	reader.ReadString('\n')
	text, _ := reader.ReadString('\n')
	s := parse(strings.TrimSpace(text))
	fmt.Println(getMaxPoints(s))
}

func parse(s string) []int {
	nn := strings.Split(s, " ")
	i := make([]int, 0, len(nn))
	for _, n := range nn {
		c, _ := strconv.Atoi(n)
		i = append(i, c)
	}
	return i
}

func getMaxPoints(s []int) int{
	even, odd := 0, 0
	for _, i := range s {
		if i % 2 == 0 {
			even += i
		} else {
			odd += i
		}
	}

	if even > odd {
		return even
	}
	return odd
}

package main

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

func main() {
	var elements []int

	reader := bufio.NewReader(os.Stdin)

	_, _ = reader.ReadString('\n')
	stringOfElements, _ := reader.ReadString('\n')

	for _, element := range strings.Fields(stringOfElements) {
		value, _ := strconv.Atoi(element)
		elements = append(elements, value)
	}

	boredomGame := NewBoredomGame(elements)
	fmt.Printf("%v", boredomGame.HighestPoint())
}

type BoredomGame struct {
	highestPoint int
	count        map[int]int
	elementSet   []int
	dp           map[int]int
}

func NewBoredomGame(elements []int) *BoredomGame {
	count, elementSet := countElementFrequency(elements)
	boredomGame := &BoredomGame{
		count:        count,
		highestPoint: 0,
		elementSet:   elementSet,
		dp:           map[int]int{0: 0},
	}
	return boredomGame
}

func countElementFrequency(elements []int) (map[int]int, []int) {
	result := map[int]int{}
	var set []int
	for _, element := range elements {
		frequency := result[element]
		if frequency == 0 {
			set = append(set, element)
		}
		result[element] += 1
	}
	return result, set
}

func (bg *BoredomGame) HighestPoint() int {
	return bg.calculatePoints()
}

func (bg *BoredomGame) calculatePoints() int {
	for _, element := range bg.elementSet {
		bg.dp[element] = Max(bg.selectElement(element-1), bg.selectElement(element-2)+(bg.count[element]*element))
		if bg.dp[element] > bg.highestPoint {
			bg.highestPoint = bg.dp[element]
		}
	}
	return bg.highestPoint
}

func Max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

func (bg *BoredomGame) selectElement(element int) int {
	if bg.dp[element] != 0 {
		return bg.dp[element]
	}
	return element * bg.count[element]
}

package main

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

func main() {
	var elements []int

	reader := bufio.NewReader(os.Stdin)

	_, _ = reader.ReadString('\n')
	stringOfElements, _ := reader.ReadString('\n')

	for _, element := range strings.Fields(stringOfElements) {
		value, _ := strconv.Atoi(element)
		elements = append(elements, value)
	}

	boredomGame := NewBoredomGame(elements)
	fmt.Printf("%v", boredomGame.HighestPoint())
}

type BoredomGame struct {
	highestPoint int
	count        map[int]int
	elementSet   []int
	dp           map[int]int
}

func NewBoredomGame(elements []int) *BoredomGame {
	count, elementSet := countElementFrequency(elements)
	boredomGame := &BoredomGame{
		count:        count,
		highestPoint: 0,
		elementSet:   elementSet,
		dp:           map[int]int{0: 0, 1: 1},
	}
	return boredomGame
}

func countElementFrequency(elements []int) (map[int]int, []int) {
	result := map[int]int{}
	var set []int
	for _, element := range elements {
		frequency := result[element]
		if frequency == 0 {
			set = append(set, element)
		}
		result[element] += 1
	}
	return result, set
}

func (bg *BoredomGame) HighestPoint() int {
	return bg.calculatePoints()
}

func (bg *BoredomGame) calculatePoints() int {
	for _, element := range bg.elementSet {
		bg.dp[element] = Max(bg.selectElement(element-1), bg.selectElement(element-2)+(bg.count[element]*element))
		if bg.dp[element] > bg.highestPoint {
			bg.highestPoint = bg.dp[element]
		}
	}
	return bg.highestPoint
}

func Max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

func (bg *BoredomGame) selectElement(element int) int {
	if bg.dp[element] != 0 {
		return bg.dp[element]
	}
	return element * bg.count[element]
}

package main

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

func main() {
	var elements []int

	reader := bufio.NewReader(os.Stdin)

	_, _ = reader.ReadString('\n')
	stringOfElements, _ := reader.ReadString('\n')

	for _, element := range strings.Fields(stringOfElements) {
		value, _ := strconv.Atoi(element)
		elements = append(elements, value)
	}

	boredomGame := NewBoredomGame(elements)
	fmt.Printf("%v", boredomGame.HighestPoint())
}

type BoredomGame struct {
	highestPoint int
	highestNum   int
	count        map[int]int
	elementSet   []int
	dp           map[int]int
}

func NewBoredomGame(elements []int) *BoredomGame {
	count, elementSet, highestNum := countElementFrequency(elements)
	boredomGame := &BoredomGame{
		count:        count,
		highestPoint: 0,
		elementSet:   elementSet,
		dp:           map[int]int{0: 0},
		highestNum:   highestNum,
	}
	return boredomGame
}

func countElementFrequency(elements []int) (map[int]int, []int, int) {
	result := map[int]int{}
	var set []int
	highestNum := 0

	for _, element := range elements {
		frequency := result[element]
		if frequency == 0 {
			set = append(set, element)
		}
		result[element] += 1
		if element > highestNum {
			highestNum = element
		}
	}
	return result, set, highestNum
}

func (bg *BoredomGame) HighestPoint() int {
	return bg.calculatePoints()
}

func (bg *BoredomGame) calculatePoints() int {
	for element := 1; element <= bg.highestNum; element++ {
		bg.dp[element] = Max(bg.dp[element-1], bg.dp[element-2]+(bg.count[element]*element))
		if bg.dp[element] > bg.highestPoint {
			bg.highestPoint = bg.dp[element]
		}
	}
	return bg.highestPoint
}

func Max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

package main

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

func main() {
	var elements []int

	reader := bufio.NewReader(os.Stdin)

	_, _ = reader.ReadString('\n')
	stringOfElements, _ := reader.ReadString('\n')

	for _, element := range strings.Fields(stringOfElements) {
		value, _ := strconv.Atoi(element)
		elements = append(elements, value)
	}

	boredomGame := NewBoredomGame(elements)
	fmt.Printf("%v", boredomGame.HighestPoint())
}

type BoredomGame struct {
	highestPoint int
	highestNum   int
	count        map[int]int
	elementSet   []int
	dp           map[int]int
}

func NewBoredomGame(elements []int) *BoredomGame {
	count, elementSet, highestNum := countElementFrequency(elements)
	boredomGame := &BoredomGame{
		count:        count,
		highestPoint: 0,
		elementSet:   elementSet,
		dp:           map[int]int{0: 0},
		highestNum:   highestNum,
	}
	return boredomGame
}

func countElementFrequency(elements []int) (map[int]int, []int, int) {
	result := map[int]int{}
	var set []int
	highestNum := 0

	for _, element := range elements {
		frequency := result[element]
		if frequency == 0 {
			set = append(set, element)
		}
		result[element] += 1
		if element > highestNum {
			highestNum = element
		}
	}
	return result, set, highestNum
}

func (bg *BoredomGame) HighestPoint() int {
	return bg.calculatePoints()
}

func (bg *BoredomGame) calculatePoints() int {
	for element:=1; element <= bg.highestNum; element++ {
		bg.dp[element] = Max(bg.selectElement(element-1), bg.selectElement(element-2)+(bg.count[element]*element))
		if bg.dp[element] > bg.highestPoint {
			bg.highestPoint = bg.dp[element]
		}
	}
	return bg.highestPoint
}

func Max(x, y int) int {
	if x < y {
		return y
	}
	return x
}

func (bg *BoredomGame) selectElement(element int) int {
	if bg.dp[element] != 0 {
		return bg.dp[element]
	}
	return element * bg.count[element]
}

// http://codeforces.com/problemset/problem/455/A
package main

import (
	"fmt"
	"bufio"
	"os"
)

// (c) Dmitriy Blokhin (sv.dblokhin@gmail.com)

const (
	MOD = 1e9 + 7
)

type (

)

func max(a, b int ) int {
	if a > b {
		return a
	}

	return b
}

func main () {
	var (
		n int
	)

	//f, _ := os.Open("input.txt")
	//input := bufio.NewReader(f)
	input := bufio.NewReader(os.Stdin)

	fmt.Fscanln(input, &n)
	m := make([]int, 1e5 + 1)

	for i := 0; i < n; i++ {
		var tmp int
		fmt.Fscan(input, &tmp)

		m[tmp]++
	}

	f := make([]int, n + 1)
	f[0] = 0
	f[1] = m[1]

	for i := 2; i <= n; i++ {
		f[i] = max(f[i - 1], f[i - 2] + m[i] * i)
	}

	fmt.Println(f[n])
}

// http://acm.timus.ru/problem.aspx?space=1&num=1741
package main

import (
	"fmt"
	"bufio"
	"os"
)

// (c) Dmitriy Blokhin (sv.dblokhin@gmail.com)

const (
	MOD = 1e9 + 7
)

type (

)

func max(a, b int ) int {
	if a > b {
		return a
	}

	return b
}

func main () {
	var (
		n int
	)

	//f, _ := os.Open("input.txt")
	//input := bufio.NewReader(f)
	input := bufio.NewReader(os.Stdin)

	fmt.Fscanln(input, &n)
	m := make([]int, 1e5 + 1)

	for i := 0; i < n; i++ {
		var tmp int
		fmt.Fscan(input, &tmp)

		m[tmp]++
	}

	f := make([]int, n)
	f[0] = 0
	f[1] = m[1]

	for i := 2; i < n; i++ {
		f[i] = max(f[i - 1], f[i - 2] + m[i] * i)
	}

	fmt.Println(f[n - 1])
}

// http://codeforces.com/problemset/problem/455/A
package main

import (
	"fmt"
	"bufio"
	"os"
)

// (c) Dmitriy Blokhin (sv.dblokhin@gmail.com)

const (
	MOD = 1e9 + 7
)

type (

)

func max(a, b int64 ) int64 {
	if a > b {
		return a
	}

	return b
}

func main () {
	var (
		n int
	)

	//f, _ := os.Open("input.txt")
	//input := bufio.NewReader(f)
	input := bufio.NewReader(os.Stdin)

	fmt.Fscanln(input, &n)
	m := make([]int, 1e5 + 1)

	for i := 0; i < n; i++ {
		var tmp int
		fmt.Fscan(input, &tmp)

		m[tmp]++
	}

	f := make([]int64, n + 1)
	f[0] = int64(0)
	f[1] = int64(m[1])

	for i := 2; i <= n; i++ {
		f[i] = max(f[i - 1], f[i - 2] + int64(m[i] * i))
	}

	fmt.Println(f[n])
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"strconv"
	"time"
	"sort"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
	array []int
	dp []int64
	was []bool
	count map[int]int
)

func f(p int) int64 {
	if p == len(array) {
		return 0
	}
	if was[p] {
		return dp[p]
	}
	was[p] = true

	if p + 1 == len(array) {
		dp[p] = int64(array[p])
	} else if array[p] != array[p + 1] + 1 {
		dp[p] = int64(count[array[p]]) * int64(array[p]) + f(p + 1)
	} else {
		dp[p] = maxInt64(int64(count[array[p]]) * int64(array[p]) + f(p + 2),
			f(p + 1))
	}
	return dp[p]
}

func solve() {
	n := readInt()
	count = make(map[int]int)
	for i := 0; i < n; i++ {
		value := readInt()
		if _, ok := count[value]; !ok {
			array = append(array, value)
		}
		count[value]++
	}
	sort.Sort(sort.Reverse(sort.IntSlice(array)))
//	logln(array)
	was = make([]bool, len(array))
	dp = make([]int64, len(array))
	printInt64(f(0))
	printLine()
}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	dbg := flag.Bool("dbg", false, "Equals true, if run is in debug mode.")
	opt := flag.Bool("opt", false, "Equals true, if run is in optimized mode.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *opt || *dbg {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
		if *dbg {
			cpuprofile, _ := os.Create("/home/outside/coding/workspace/go/io/cpuprofile.txt")
			pprof.StartCPUProfile(cpuprofile)
			defer cpuprofile.Close()
			defer pprof.StopCPUProfile()
		}
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// Maximum size used to buffer a token. The actual maximum token size
	// may be smaller as the buffer may need to include, for instance, a newline.
	MaxScanTokenSize = 1 << 20
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is neded.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return 0, nil, nil
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"strconv"
	"time"
	"sort"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
	array []int
	dp []int64
	was []bool
	count map[int]int
)

func f(p int) int64 {
	if p == len(array) {
		return 0
	}
	if was[p] {
		return dp[p]
	}
	was[p] = true

	if p + 1 == len(array) {
		dp[p] = int64(array[p])
	} else if array[p] != array[p + 1] + 1 {
		dp[p] = int64(array[p]) + f(p + 1)
	} else {
		dp[p] = maxInt64(int64(count[array[p]]) * int64(array[p]) + f(p + 2),
			f(p + 1))
	}
	return dp[p]
}

func solve() {
	n := readInt()
	count = make(map[int]int)
	for i := 0; i < n; i++ {
		value := readInt()
		if _, ok := count[value]; !ok {
			array = append(array, value)
		}
		count[value]++
	}
	sort.Sort(sort.Reverse(sort.IntSlice(array)))
//	logln(array)
	was = make([]bool, len(array))
	dp = make([]int64, len(array))
	printInt64(f(0))
	printLine()
}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	dbg := flag.Bool("dbg", false, "Equals true, if run is in debug mode.")
	opt := flag.Bool("opt", false, "Equals true, if run is in optimized mode.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *opt || *dbg {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
		if *dbg {
			cpuprofile, _ := os.Create("/home/outside/coding/workspace/go/io/cpuprofile.txt")
			pprof.StartCPUProfile(cpuprofile)
			defer cpuprofile.Close()
			defer pprof.StopCPUProfile()
		}
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// Maximum size used to buffer a token. The actual maximum token size
	// may be smaller as the buffer may need to include, for instance, a newline.
	MaxScanTokenSize = 1 << 20
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is neded.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return 0, nil, nil
}

package main

import "fmt"

func main() {
	var n int
	fmt.Scan(&n)
	c := make([]int, 10e5+1)
	for i := 0; i < n; i++ {
		var ai int
		fmt.Scan(&ai)
		c[ai] = c[ai] + 1
	}
	var s int
	for i := int(10e5); i > 0; i-- {
		cv := c[i] * i
		nv := c[i-1] * (i - 1)
		if i != 10e5 {
			nv += (c[i+1] * (i + 1))
		}
		if cv > nv {
			s += cv
			c[i-1] = 0
		}
	}
	fmt.Print(s)
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scan(&n)
	s, _ := bufio.NewReader(os.Stdin).ReadString('\n')
	fmt.Println(s)
	ts := strings.Split(s[:len(s)-1], " ")
	fmt.Println(ts)
	c := make([]int, N+1)
	for _, t := range ts {
		i, _ := strconv.Atoi(t)
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scanf("%d\n", &n)
	s, _ := bufio.NewReader(os.Stdin).ReadString('\n')
	ts := strings.Split(s[:len(s)-1], " ")
	c := make([]int, N+1)
	for _, t := range ts {
		i, _ := strconv.Atoi(t)
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scan(&n)
	s, _ := bufio.NewReader(os.Stdin).ReadString('\n')
	ts := strings.Split(s[:len(s)-1], " ")
	c := make([]int, N+1)
	for _, t := range ts {
		i, _ := strconv.Atoi(t)
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scanf("%d\n", &n)
	sc := bufio.NewScanner(os.Stdin)
	c := make([]int64, N+1)
	for i := 0; i < n; i++ {
		sc.Scan()
		i, _ := strconv.Atoi(sc.Text())
		c[i] = c[i] + 1
	}
	dp := make([]int64, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+int64(i)*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

package main

import (
	"fmt"
	"math"
)

const N = 10e5

func main() {
	var n int
	fmt.Scan(&n)
	c := make([]int, N+1)
	for i := 0; i < n; i++ {
		var ai int
		fmt.Scan(&ai)
		c[ai] = c[ai] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = dp[i-2] + i*c[i]
	}
	m := math.Max(float64(dp[N-1]), float64(dp[N]))
	fmt.Print(m)
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scan(&n)
	s, err := bufio.NewReader(os.Stdin).ReadString('\n')
	if err != nil {
		s, err = bufio.NewReader(os.Stdin).ReadString('\r')
		if err != nil {
			fmt.Println(err)
		}
	}
	ts := strings.Split(s[:len(s)-1], " ")
	c := make([]int, N+1)
	for _, t := range ts {
		i, _ := strconv.Atoi(t)
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scanf("%d", &n)
	sc := bufio.NewScanner(os.Stdin)
	c := make([]int64, N+1)
	for i := 0; i < n; i++ {
		sc.Scan()
		i, _ := strconv.Atoi(sc.Text())
		c[i] = c[i] + 1
	}
	dp := make([]int64, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+int64(i)*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
	fmt.Println(strconv.IntSize)
	var n int
	fmt.Scanf("%d\n", &n)
	sc := bufio.NewScanner(os.Stdin)
	c := make([]int, N+1)
	for i := 0; i < n; i++ {
		sc.Scan()
		i, _ := strconv.Atoi(sc.Text())
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

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

const N = 10e5

func main() {
	var n int
	fmt.Scanf("%d\n", &n)
	s, _ := bufio.NewReader(os.Stdin).ReadString('\r')
	ts := strings.Split(s[:len(s)-1], " ")
	c := make([]int, N+1)
	for _, t := range ts {
		i, _ := strconv.Atoi(t)
		c[i] = c[i] + 1
	}
	dp := make([]int, N+1)
	dp[1] = c[1]
	for i := 2; i <= N; i++ {
		dp[i] = max(dp[i-2]+i*c[i], dp[i-1])
	}
	fmt.Print(dp[N])
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

package main

// some kind of dynamic programming problems...?

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

const isDebug = false

func main() {
	var numbers int
	var finalScore int

	fmt.Scanln(&numbers)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	mappedCounter := make(map[int]int)

	for i := 0; i < numbers; i++ {
		scanner.Scan()
		v, _ := strconv.Atoi(scanner.Text())

		if _, exists := mappedCounter[v]; exists {
			mappedCounter[v]++
		} else {
			mappedCounter[v] = 1
		}
	}

	// Calculations...
	for len(mappedCounter) > 0 {
		prevLosingScore := math.MinInt32
		chosen := -1

		for k, v := range(mappedCounter) {
			losing := 0

			if _, exists := mappedCounter[k-1]; exists {
				losing -= mappedCounter[k-1] * (k-1)
			}

			if _, exists := mappedCounter[k+1]; exists {
				losing -= mappedCounter[k+1] * (k+1)
			}

			if isDebug {
				fmt.Println("For = ", k, ", loss score is ", losing)
			}

			if prevLosingScore < losing {
				prevLosingScore = losing
				chosen = k
			} else if prevLosingScore == losing {
				// Take better one if both scores are same
				if chosen * mappedCounter[chosen] < k*v{
					chosen = k
				}
			} else {
				// nothing to do
			}
		}

		if chosen < 1 {
			panic("should not reach here (chosen number is smaller than 1")
		}

		delete(mappedCounter, chosen-1)
		delete(mappedCounter, chosen+1)

		finalScore += chosen
		mappedCounter[chosen]--

		if mappedCounter[chosen] == 0 {
			delete(mappedCounter, chosen)
		}

		if isDebug {
			fmt.Println("By choosing = ", chosen, ", accumulated score is ", finalScore, ", Kill ", chosen-1, " and ", chosen+1)
		}

		if isDebug {
			fmt.Println("Calculate score of ", chosen, " and delete key. Remains: ", len(mappedCounter))
		}
	}

	fmt.Println(finalScore)
}

package main

// some kind of dynamic programming problems...?

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

const isDebug = true

func main() {
	var numbers int

	fmt.Scanln(&numbers)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	arrayCounter := make([]int, numbers + 10)
	dpCounter := make([]int, numbers + 10)

	for i := 0; i < numbers; i++ {
		scanner.Scan()
		v, _ := strconv.Atoi(scanner.Text())

		arrayCounter[v]++
	}

	dpCounter[0] = 0
	dpCounter[1] = arrayCounter[1]

	// take previous calculation result, and reflect it to next calculation
	for i := 2; i <= numbers; i++ {
		a := dpCounter[i-2] + arrayCounter[i] * i
		b := dpCounter[i-1]

		if a < b {
			dpCounter[i] = b
		} else {
			dpCounter[i] = a
		}
	}

	fmt.Println(dpCounter[numbers])
}

package main

// some kind of dynamic programming problems...?

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

const isDebug = true

func main() {
	var numbers int

	fmt.Scanln(&numbers)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	arrayCounter := make([]int64, 100000 + 10)
	dpCounter := make([]int64, 100000 + 10)

	for i := 0; i < numbers; i++ {
		scanner.Scan()
		v, _ := strconv.Atoi(scanner.Text())

		arrayCounter[v]++
	}

	dpCounter[0] = 0
	dpCounter[1] = arrayCounter[1]

	// take previous calculation result, and reflect it to next calculation
	for i := 2; i <= numbers; i++ {
		a := dpCounter[i-2] + arrayCounter[i] * int64(i)
		b := dpCounter[i-1]

		if a < b {
			dpCounter[i] = b
		} else {
			dpCounter[i] = a
		}
	}

	fmt.Println(dpCounter[numbers])
}

package main

// some kind of dynamic programming problems...?

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

func main() {
	var numbers int
	var finalScore int

	fmt.Scanln(&numbers)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	mappedCounter := make(map[int]int)

	for i := 0; i < numbers; i++ {
		scanner.Scan()
		v, _ := strconv.Atoi(scanner.Text())

		if _, exists := mappedCounter[v]; exists {
			mappedCounter[v]++
		} else {
			mappedCounter[v] = 1
		}
	}

	// Calculations...
	for len(mappedCounter) > 0 {
		prevLosingScore := math.MinInt32
		chosen := -1

		for k, v := range(mappedCounter) {
			losing := 0

			if _, exists := mappedCounter[k-1]; exists {
				losing -= mappedCounter[k-1] * (k-1)
			}

			if _, exists := mappedCounter[k+1]; exists {
				losing -= mappedCounter[k+1] * (k+1)
			}

			// fmt.Println("For = ", k, ", loss score is ", losing)

			if prevLosingScore < losing {
				prevLosingScore = losing
				chosen = k
			} else if prevLosingScore == losing {
				// Take better one if both scores are same
				if chosen * mappedCounter[chosen] < k*v{
					chosen = k
				}
			} else {
				// nothing to do
			}
		}

		if chosen < 1 {
			panic("should not reach here (chosen number is smaller than 1")
		}

		delete(mappedCounter, chosen-1)
		delete(mappedCounter, chosen+1)

		finalScore += mappedCounter[chosen] * chosen
		//fmt.Println("By choosing = ", chosen, ", accumulated score is ", finalScore, ", Kill ", chosen-1, " and ", chosen+1)

		delete(mappedCounter, chosen)
		//fmt.Println("Calculate score of ", chosen, " and delete key. Remains: ", len(mappedCounter))
	}

	fmt.Println(finalScore)
}

package main

import "fmt"

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func main() {
	var N int
	fmt.Scanf("%d\n", &N)

	var x int
	for i := 0; i < N; i++ {
		fmt.Scanf("%d", &x)
		fmt.Println(x)
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import "fmt"

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func main() {
	var N int
	fmt.Scanf("%d", &N)

	var x int
	for i := 0; i < N; i++ {
		fmt.Scanf("%d", &x)
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

var reader *bufio.Reader

func init() {
	reader = bufio.NewReader(os.Stdin)
}

func readInt() int {
	var t int
	for i, _ := reader.ReadByte(); i >= '0' && i <= '9'; i, _ = reader.ReadByte() {
		t = t*10 + int(i-'0')
	}
	return t
}

func main() {
	var N int = readInt()

	var x int
	for i := 0; i < N; i++ {
		x = readInt()
		H[x]++
	}

	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		H[i] = max(H[i], H[i-1])
	}
	fmt.Println(H[MAXN-1])
}

package main

import "fmt"

const MAXN = 100001

var H [MAXN]int64

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func main() {
	var N int
	fmt.Scan(&N)

	var x int
	for i := 0; i < N; i++ {
		fmt.Scan(&x)
		H[x]++
	}

	var ans int64
	for i := 1; i < MAXN; i++ {
		H[i] = int64(i) * H[i]
		if i >= 2 {
			H[i] = H[i] + H[i-2]
		}
		ans = max(H[i], H[i-1])
	}
	fmt.Println(ans)
}