#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque
def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)

    while stack:
        u = stack.pop()
        if used[u]:
            continue

        used[u] = True
        for v in reversed(edge[u]):
            if not used[v]:
                stack.append(v)

        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]

        if a[u] > 0: order1.append(u)
        else: order2.append(u)

# def dfs(u):
#     global ans, used, order1, order2, edge, a, b

#     try: used[u] = True
#     except: print("used error")
#     # for v in edge.get(u, []):
#     try: edges = edge[u]
#     except: print("edges error")

#     for v in edge[u]:
#         if not used[v]:
#             try: dfs(v)
#             except: print("error inside")

#     try:
#         ans += a[u]
#         if b[u] != -1 and a[u] > 0:
#             a[b[u]] += a[u]
#     except:
#         print("posterror")

#     if a[u] > 0: order1.append(u)
#     else: order2.append(u)

for i in range(n):
    if not used[i]:
        # try:
        dfs(i)
        # except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    # for v in edge.get(u, []):
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


# import sys, threading
# # resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
# sys.setrecursionlimit(10**8)
# threading.stack_size(2*10**8)

#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

# def dfs(u):
#     global ans, used, order1, order2, edge, a, b
#     stack = deque()
#     stack.append(u)
#     # post_process(u)

#     while stack:
#         u = stack.pop()
#         if used[u]: continue
#         used[u] = True
#         # print(u)

#         for v in edge[u]:
#             if not used[v]:
#                 used[u] = True
#                 stack.append(v)

#         print(u)
#         post_process(u)
#     return used

from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

@bootstrap
def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            used = yield dfs(v)

    # print(u)
    post_process(u)
    yield used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


import sys, threading
# resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**8)
threading.stack_size(2*10**8)

#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        # print(u)

        for v in edge[u]:
            if not used[v]:
                used[u] = True
                stack.append(v)

        print(u)
        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    # print(u)
    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        print(u)

        for v in edge[u]:
            if not used[v]:
                stack.append(v)
                # post_process(v)

        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            MAX_LIMIT = 2_000_000_000

            with RecursionLimit(MAX_LIMIT):
                dfs(v)

    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

# def dfs(u):
#     global ans, used, order1, order2, edge, a, b
#     stack = deque()
#     stack.append(u)
#     # post_process(u)

#     while stack:
#         u = stack.pop()
#         if used[u]: continue
#         # if not used[u]:
#         used[u] = True
#         # print(u)

#         for v in edge[u]:
#             if not used[v]:
#                 stack.append(v)
#                 # post_process(v)

#         post_process(u)

import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try:
            MAX_LIMIT = 1000_000
            with RecursionLimit(MAX_LIMIT):
                dfs(i)
        except: print("dfs error")

print(ans)

# # import sys
# for i, o in enumerate(order1):
#     print(o+1, "",end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# for i, o in enumerate(reversed(order2)):
#     print(o+1, "", end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# print()

# print(edge)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

# print(n, a, b)

#--------------------------------------
edge = {i: [] for i in range(n)}
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    if i % 1000 == 0: sys.stdout.flush()
print()

# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

# def dfs(u):
#     global ans, used, order1, order2, edge, a, b
#     stack = deque()
#     stack.append(u)
#     # post_process(u)

#     while stack:
#         u = stack.pop()
#         if used[u]: continue
#         # if not used[u]:
#         used[u] = True
#         # print(u)

#         for v in edge[u]:
#             if not used[v]:
#                 stack.append(v)
#                 # post_process(v)

#         post_process(u)

import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try:
            MAX_LIMIT = 10000
            with RecursionLimit(MAX_LIMIT):
                dfs(i)
        except: print("dfs error")

print(ans)

# # import sys
# for i, o in enumerate(order1):
#     print(o+1, "",end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# for i, o in enumerate(reversed(order2)):
#     print(o+1, "", end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# print()

# print(edge)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        # try:
        dfs(i)
        # except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            dfs(v)

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try: dfs(i)
        except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        print(u)

        for v in edge[u]:
            if not used[v]:
                stack.append(v)
                # post_process(v)

        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        MAX_LIMIT = 2_000_000_000
        with RecursionLimit(MAX_LIMIT):
            used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().split()))
b = list(map(int, input().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    # for v in edge.get(u, []):
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


import resource, sys
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**6)

#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        # print(u)

        for v in edge[u]:
            if not used[v]:
                used[u] = True
                stack.append(v)

        print(u)
        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    # print(u)
    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


import sys, threading
# resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**8)
threading.stack_size(10**8)

#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        # print(u)

        for v in edge[u]:
            if not used[v]:
                used[u] = True
                stack.append(v)

        print(u)
        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    # print(u)
    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


from types import GeneratorType

def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack: return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack: break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

#--------------- Take Input ---------------------
n = int(input())
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------- Preprocess ----------
edge = [[] for i in range(n)]
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
# print(edge, a, b)

#----------------- Solve ---------------------
used = [False]*n
order1, order2 = [], []
ans = 0

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

@bootstrap
def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            yield dfs(v)
    post_process(u)
    yield

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

# def dfs(u):
#     global ans, used, order1, order2, edge, a, b
#     stack = deque()
#     stack.append(u)
#     # post_process(u)

#     while stack:
#         u = stack.pop()
#         if used[u]: continue
#         # if not used[u]:
#         used[u] = True
#         # print(u)

#         for v in edge[u]:
#             if not used[v]:
#                 stack.append(v)
#                 # post_process(v)

#         post_process(u)

import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try:
            MAX_LIMIT = 1000_000_000
            with RecursionLimit(MAX_LIMIT):
                dfs(i)
        except: print("dfs error")

print(ans)

# # import sys
# for i, o in enumerate(order1):
#     print(o+1, "",end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# for i, o in enumerate(reversed(order2)):
#     print(o+1, "", end="")
#     # if i % 1000 == 0: sys.stdout.flush()
# print()

# print(edge)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(200_000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        # try:
        dfs(i)
        # except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

# print(n, a, b)

#--------------------------------------
edge = {i: [] for i in range(n)}
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)
for o in order1: print(o+1, "",end="")
for o in reversed(order2): print(o+1, "", end="")
print()

# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

'''
3
1 2 3
2 3 -1
'''


from itertools import permutations
from copy import deepcopy

def operate(a, b, i, ans):
    ans += a[i]
    if b[i] != -1: a[b[i]] += a[i]

    return ans, a

n = int(input())
a = [None] + [int(i) for i in input().split()]
b = [None] + [int(i) for i in input().split()]

ans = 0
# print(n, a, b)
ans_max = 0
max_perm = []
for perm in permutations(list(range(1, n+1))):
    ans_ = deepcopy(ans)
    a_ = deepcopy(a)
    b_ = deepcopy(b)

    for pi in perm:
        ans_, a_ = operate(a_, b_, pi, ans_)

    if ans_max < ans_:
        ans_max = ans_
        max_perm = list(perm)

    # print(perm, ans_)

print(ans_max)
print(' '.join(str(p) for p in max_perm))

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

# print(n, a, b)

#--------------------------------------
edge = {i: [] for i in range(n)}
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        print(u)

        for v in edge[u]:
            if not used[v]:
                stack.append(v)
                # post_process(v)

        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        MAX_LIMIT = 2_000_000_000_000
        with RecursionLimit(MAX_LIMIT):
            used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            dfs(v)

    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try: dfs(i)
        except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


import sys, threading
# resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**6)
threading.stack_size(10**8)

#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        # print(u)

        for v in edge[u]:
            if not used[v]:
                used[u] = True
                stack.append(v)

        print(u)
        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)

    # print(u)
    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            dfs(v)

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        # try:
        dfs(i)
        # except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(long, input().strip().split()))
b = list(map(long, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    # for v in edge.get(u, []):
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().split()))
b = list(map(int, input().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
edge = dict()
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        # edge[b[i]].append(i)
        edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    for v in edge.get(u, []):
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    try: used[u] = True
    except: print("used error")
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            try: dfs(v)
            except: print("error inside")

    try:
        ans += a[u]
        if b[u] != -1 and a[u] > 0:
            a[b[u]] += a[u]
    except:
        print("posterror")

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        # try:
        dfs(i)
        # except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().split()))
b = list(map(int, input().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    # for v in edge.get(u, []):
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)

import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

# print(n, a, b)

#--------------------------------------
edge = {i: [] for i in range(n)}
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    used[u] = True
    # for v in edge.get(u, []):
    try: edges = edge[u]
    except: print("edges error")

    for v in edge[u]:
        if not used[v]:
            dfs(v)

    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try: dfs(i)
        except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)
import sys

class RecursionLimit:
    def __init__(self, limit):
        self.limit = limit
        self.cur_limit = sys.getrecursionlimit()

    def __enter__(self):
        sys.setrecursionlimit(self.limit)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.setrecursionlimit(self.cur_limit)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

from collections import deque

def post_process(u):
    global ans, used, order1, order2, edge, a, b
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    stack = deque()
    stack.append(u)
    # post_process(u)

    while stack:
        u = stack.pop()
        if used[u]: continue
        used[u] = True
        print(u)

        for v in edge[u]:
            if not used[v]:
                stack.append(v)
                # post_process(v)

        post_process(u)
    return used

def dfs(u):
    global ans, used, order1, order2, edge, a, b
    used[u] = True
    for v in edge[u]:
        if not used[v]:
            MAX_LIMIT = 2_000_000_000_000

            with RecursionLimit(MAX_LIMIT):
                dfs(v)

    post_process(u)
    return used

for i in range(n):
    if not used[i]:
        used = dfs(i)

print(ans)
print(" ".join(str(o+1) for o in order1), end=' ')
print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
for /l %x in (1, 1, 3) do python cf_1388_d.py < input\cf_1388_d_%x
'''


#-----------------Take Input---------------------
n = int(input())
# a = [None] + [int(i) for i in input().split()]
# b = [None] + [int(i) for i in input().split()]

# a = [int(i) for i in input().split()]
# b = [int(i) for i in input().split()]
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))

# print(n, a, b)

#--------------------------------------
# edge = {i: [] for i in range(n)}
# edge = dict()
edge = [[] for i in range(n)]
# edge
for i, x in enumerate(b):
    if x != -1:
        b[i] -= 1
        edge[b[i]].append(i)
        # edge[b[i]] = edge.get(b[i], [])+[i]

# print(edge, a, b)

used = [False]*n
order1, order2 = [], []
ans = 0

def dfs(u):
    global ans, used, order1, order2, edge, a, b

    used[u] = True
    # for v in edge.get(u, []):
    for v in edge[u]:
        if not used[v]:
            dfs(v)
    ans += a[u]
    if b[u] != -1 and a[u] > 0:
        a[b[u]] += a[u]

    if a[u] > 0: order1.append(u)
    else: order2.append(u)

for i in range(n):
    if not used[i]:
        try: dfs(i)
        except: print("dfs error")

print(ans)

# import sys
for i, o in enumerate(order1):
    print(o+1, "",end="")
    # if i % 1000 == 0: sys.stdout.flush()
for i, o in enumerate(reversed(order2)):
    print(o+1, "", end="")
    # if i % 1000 == 0: sys.stdout.flush()
print()

# print(edge)
# print(" ".join(str(o+1) for o in order1), end=' ')
# print(" ".join(str(o+1) for o in reversed(order2)))

''' generate
with open('in', 'w') as f:
    f.write(str(200000))
    f.write('\n')
    sign = 1
    for i in range(200_000):
        f.write(f'{-200000*sign} ')
    f.write('\n')
    for i in range(200_000):
        f.write(f'{i+1} ')

'''

'''
3
1 2 3
2 3 -1
'''


import sys

sys.setrecursionlimit(2 * 10 ** 5)

n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
ans = 0

def construct_graph(A, B):
    graph = {}
    for i, j in enumerate(B):
        if a[i] is not None:
            graph[i + 1] = j
    return graph

def dfs(G, x, FINISHED_ORDER, VISITED):
    if x in VISITED:
        return
    if x in G and G[x] != -1:
        dfs(G, G[x], FINISHED_ORDER, VISITED)
    FINISHED_ORDER.append(x)
    VISITED[x] = True

def get_topological_sort(G):
    visited = {}
    finished_order = []

    for x in G:
        dfs(G, x, finished_order, visited)
    finished_order.reverse()
    return finished_order

def get_iterative_topological_sort(G):
    finished_order = []
    already_removed = {}
    for x in G:
        if x in already_removed:
            continue
        stack = [x]
        while len(stack) != 0:
            x = stack.pop()
            if x in already_removed:
                finished_order.append(x)
                continue

            # reappend x
            stack.append(x)
            # append x's children (well in this case only 1 child)
            if x in G and G[x] != -1 and G[x] not in already_removed:
                stack.append(G[x])
            already_removed[x] = True

    finished_order.reverse()
    return finished_order

g = construct_graph(a, b)
take_first = []
take_last = []
ans = 0
TOP = get_iterative_topological_sort(g)
TOP.reverse()

while len(TOP) != 0:
    node_to_select = TOP.pop()
    if a[node_to_select - 1] is None:
        continue
    if a[node_to_select - 1] >= 0:
        take_first.append(node_to_select)
        ans += a[node_to_select - 1]
        # apply changes to neighbour node : only if we know we select the node before its neighbour
        if b[node_to_select - 1] != -1:
            a[b[node_to_select - 1] - 1] += a[node_to_select - 1]

    else:
        take_last.append(node_to_select)
        ans += a[node_to_select - 1]

    a[node_to_select - 1] = None

print(ans)
sol = take_first + take_last[::-1]
sol = list(map(str, sol))
print(" ".join(sol))


import java.io.*;
import java.util.*;
public class B375
{
    public static void main(String args[])throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s[]=br.readLine().trim().split(" ");
        int n=Integer.parseInt(s[0]);
        int m=Integer.parseInt(s[1]);
        int arr[][]=new int[n+1][m+1];
        int last[][]=new int[n+1][m+1];
        for(int i=1;i<=n;i++)
        {
            String ss=br.readLine().trim();
            for(int j=1;j<=m;j++)
            {
                arr[i][j]=ss.charAt(j-1)-'0';
                if(arr[i][j]==1)
                {
                    if(arr[i][j-1]==1)
                        last[i][j]=last[i][j-1];
                    else
                        last[i][j]=j;
                }
                //System.out.print(last[i][j]+" ");
            }
            //System.out.println();
        }
        int max=0;
        for(int i=1;i<=m;i++)
        {
            int a[]=new int[m+2];
            //System.out.println(i);
            for(int j=1;j<=n;j++)
            {
                if(arr[j][i]==1)
                {
                    int x=last[j][i];
                    a[x]++;
                    a[i+1]--;
                    //System.out.println(j+" "+x);
                }
            }
            for(int j=1;j<=i;j++)
            {
                a[j]+=a[j-1];
                //System.out.print(a[j]+" ");
            }
            //System.out.println();
            int min=m*2;
            for(int j=i;j>=1;j--)
            {
                min=Math.min(min,a[j]);
                //int area=min*(j-i+1);
//                if(i==5)
//                {
//                    System.out.print(area+" ");
//                }
                max=Math.max(max,min*(i-j+1));

            }
            //System.out.println();
        }
        System.out.println(max);

    }

}


package dp;
import java.io.*;
import java.util.*;
public class B375
{
    public static void main(String args[])throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s[]=br.readLine().split(" ");
        int n=Integer.parseInt(s[0]);
        int m=Integer.parseInt(s[1]);
        int arr[][]=new int[n+1][m];
        for(int i=0;i<n;i++)
        {
            String str=br.readLine();
            int temp[]=new int[m];
            for(int j=0;j<m;j++)
            {
                temp[j]=str.charAt(j)-48;
            }
            Arrays.sort(temp);
            for(int j=0;j<m;j++)
            {
                arr[i+1][j]=temp[j];
            }
        }
        int start[]=new int[n+1];
        int dp[]=new int[n+1];
        for(int i=1;i<=n;i++)
        {
            int flag=0;
            for(int j=0;j<m;j++)
            {
                if(arr[i][j]==1)
                {
                    start[i]=j;
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                start[i]=n;
        }
        int curr=m-start[0],c=0;
        for(int i=1;i<=n;i++)
        {
            if(m-start[i] == 0)
            {
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
                curr=0;
                c=0;
            }
            else if(curr==0)
            {
                if(start[i]!=n)
                {
                    curr=n-start[i];
                    c++;
                }
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
            }
            else
            {
                curr=(int)(Math.min(curr,m-start[i]));
                c++;
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
            }
        }
        System.out.println(dp[n]);
    }
}


import java.io.*;
import java.util.*;
public class B375
{
    public static void main(String args[])throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s[]=br.readLine().split(" ");
        int n=Integer.parseInt(s[0]);
        int m=Integer.parseInt(s[1]);
        int arr[][]=new int[n+1][m];
        for(int i=0;i<n;i++)
        {
            String str=br.readLine();
            int temp[]=new int[m];
            for(int j=0;j<m;j++)
            {
                temp[j]=str.charAt(j)-48;
            }
            Arrays.sort(temp);
            for(int j=0;j<m;j++)
            {
                arr[i+1][j]=temp[j];
            }
        }
        int start[]=new int[n+1];
        int dp[]=new int[n+1];
        for(int i=1;i<=n;i++)
        {
            int flag=0;
            for(int j=0;j<m;j++)
            {
                if(arr[i][j]==1)
                {
                    start[i]=j;
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                start[i]=n;
        }
        int curr=m-start[0],c=0;
        for(int i=1;i<=n;i++)
        {
            if(m-start[i] == 0)
            {
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
                curr=0;
                c=0;
            }
            else if(curr==0)
            {
                if(start[i]!=n)
                {
                    curr=n-start[i];
                    c++;
                }
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
            }
            else
            {
                curr=(int)(Math.min(curr,m-start[i]));
                c++;
                dp[i]=(int)(Math.max(dp[i-1],curr*c));
            }
        }
        System.out.println(dp[n]);
    }
}


import java.io.*;
import java.util.*;
public class B375
{
    public static void main(String args[])throws IOException
    {
        Reader sc=new Reader();
        int n=sc.nextInt();
        int m=sc.nextInt();
        int arr[][]=new int[n+1][m+1];
        int last[][]=new int[n+1][m+1];
        for(int i=1;i<=n;i++)
        {
            String s=sc.readLine();
            for(int j=1;j<=m;j++)
            {
                arr[i][j]=s.charAt(j-1)-'0';
                if(arr[i][j]==1)
                {
                    if(arr[i][j-1]==1)
                        last[i][j]=last[i][j-1];
                    else
                        last[i][j]=j;
                }
                //System.out.print(last[i][j]+" ");
            }
            //System.out.println();
        }
        int max=0;
        for(int i=1;i<=m;i++)
        {
            int a[]=new int[m+2];
            //System.out.println(i);
            for(int j=1;j<=n;j++)
            {
                if(arr[j][i]==1)
                {
                    int x=last[j][i];
                    a[x]++;
                    a[i+1]--;
                    //System.out.println(j+" "+x);
                }
            }
            for(int j=1;j<=i;j++)
            {
                a[j]+=a[j-1];
                //System.out.print(a[j]+" ");
            }
            //System.out.println();
            int min=m*2;
            for(int j=i;j>=1;j--)
            {
                min=Math.min(min,a[j]);
                //int area=min*(j-i+1);
//                if(i==5)
//                {
//                    System.out.print(area+" ");
//                }
                max=Math.max(max,min*(i-j+1));

            }
            //System.out.println();
        }
        System.out.println(max);

    }

}
class Reader {
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte [] buffer;
		private int bufferPointer, bytesRead;

		public Reader () {
			din = new DataInputStream (System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader (String file_name) throws IOException {
			din = new DataInputStream (new FileInputStream (file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String readLine () throws IOException {
			byte [] buf = new byte[1024];
			int cnt = 0, c;
			while ((c = read ()) != -1) {
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String (buf, 0, cnt);
		}

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

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

		public double nextDouble () throws IOException {
			double ret = 0, div = 1;
			byte c = read ();
			while (c <= ' ')
				c = read ();
			boolean neg = (c == '-');
			if (neg)
				c = read ();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read ()) >= '0' && c <= '9');
			if (c == '.')
				while ((c = read ()) >= '0' && c <= '9')
					ret += (c - '0') / (div *= 10);
			if (neg)
				return -ret;
			return ret;
		}

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

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

		public void close () throws IOException {
			if (din == null)
				return;
			din.close ();
		}
	}


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

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

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out){
	    int n = in.ri(), m = in.ri();
	    char[][] tab = IOUtils.readTable(in, n, m);
	    int[][] mem = new int[n][m];
	    for(int row = 0; row < n; row++) {
		    for(int col = m - 1; col >= 0; col--){
			    if (tab[row][col] == '1') mem[row][col] = (col == m - 1) ? 1 : mem[row][col + 1] + 1;
		    }
	    }
	    int res = 0;
	    for(int col = 0; col < m; col++) {
		    int[] curcolvals = new int[n];
		    for(int i = 0; i < n; i++) curcolvals[i] = mem[i][col];
		    ArrayUtils.ss(curcolvals);
		    ArrayUtils.reverse(curcolvals);
		    for(int i = 0; i < curcolvals.length; i++) {
			    int howmany = i + 1;
			    int width = curcolvals[i];
			    res = Math.max(res, howmany * width);
		    }
	    }
	    out.printLine(res);
    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

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

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

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

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IOUtils {
	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}
	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}
}

class ArrayUtils {
	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}
	public static void ss(int[] arr){
		int n = arr.length;
		Random rnd = new Random();
		for(int i=0; i<n; ++i){
			int tmp = arr[i];
			int randomPos = i + rnd.nextInt(n-i);
			arr[i] = arr[randomPos];
			arr[randomPos] = tmp;
		}
		Arrays.sort(arr);
	}
}


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

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

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out){
	    int n = in.ri(), m = in.ri(), res = 0;
	    char[][] tab = IOUtils.readTable(in, n, m);
	    int[][] mem = new int[n][m];
	    for(int row = 0; row < n; row++) {
		    for(int col = m - 1; col >= 0; col--){
			    if (tab[row][col] == '1') mem[row][col] = (col == m - 1) ? 1 : mem[row][col + 1] + 1;
		    }
	    }
	    for(int col = 0; col < m; col++) {
		    int[] curcolvals = new int[n];
		    for(int i = 0; i < n; i++) curcolvals[i] = mem[i][col];
		    Arrays.sort(curcolvals);
		    ArrayUtils.reverse(curcolvals);
		    for(int i = 0; i < curcolvals.length; i++) {
			    int howmany = i + 1;
			    int width = curcolvals[i];
			    res = Math.max(res, howmany * width);
		    }
	    }
	    out.printLine(res);

    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

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

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

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

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IOUtils {
	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}
	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}
}

class ArrayUtils {
	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}
}


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

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

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out){
	    int n = in.ri(), m = in.ri(), res = 0;
	    char[][] tab = IOUtils.readTable(in, n, m);
	    int[][] mem = new int[n][m];
	    for(int row = 0; row < n; row++) {
		    for(int col = m - 1; col >= 0; col--){
			    if (tab[row][col] == '1') mem[row][col] = (col == m - 1) ? 1 : mem[row][col + 1] + 1;
		    }
	    }
	    for(int col = 0; col < m; col++) {
		    int[] curcolvals = new int[n];
		    for(int i = 0; i < n; i++) curcolvals[i] = mem[i][col];
		    ArrayUtils.ss(curcolvals);
		    ArrayUtils.reverse(curcolvals);
		    for(int i = 0; i < curcolvals.length; i++) {
			    int howmany = i + 1;
			    int width = curcolvals[i];
			    res = Math.max(res, howmany * width);
		    }
	    }
	    out.printLine(res);

    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

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

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

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

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IOUtils {
	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}
	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}
}

class ArrayUtils {
	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}
	public static void ss(int[] arr){
		int n = arr.length;
		Random rnd = new Random();
		for(int i=0; i<n; ++i){
			int tmp = arr[i];
			int randomPos = i + rnd.nextInt(n-i);
			arr[i] = arr[randomPos];
			arr[randomPos] = tmp;
		}
		Arrays.sort(arr);
	}
}


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

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

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out){
	    int n = in.ri(), m = in.ri(), res = 0;
	    char[][] tab = IOUtils.readTable(in, n, m);
	    int[][] mem = new int[n][m];
	    for(int row = 0; row < n; row++) {
		    for(int col = m - 1; col >= 0; col--){
			    if (tab[row][col] == '1') mem[row][col] = (col == m - 1) ? 1 : mem[row][col + 1] + 1;
		    }
	    }
	    for(int col = 0; col < m; col++) {
		    int[] curcolvals = new int[n];
		    for(int i = 0; i < n; i++) curcolvals[i] = mem[i][col];
		    ArrayUtils.radixsort(curcolvals);
		    ArrayUtils.reverse(curcolvals);
		    for(int i = 0; i < curcolvals.length; i++) {
			    int howmany = i + 1;
			    int width = curcolvals[i];
			    res = Math.max(res, howmany * width);
		    }
	    }
	    out.printLine(res);

    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

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

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

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

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IOUtils {
	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}
	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}
}

class ArrayUtils {
	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}
	public static void radixsort(int[] input) {
		final int RADIX = 10;
		List<Integer>[] bucket = new ArrayList[RADIX];
		for (int i = 0; i < bucket.length; i++) {
			bucket[i] = new ArrayList<Integer>();
		}

		boolean maxLength = false;
		int tmp = -1, placement = 1;
		while (!maxLength) {
			maxLength = true;
			for (Integer i : input) {
				tmp = i / placement;
				bucket[tmp % RADIX].add(i);
				if (maxLength && tmp > 0) {
					maxLength = false;
				}
			}
			int a = 0;
			for (int b = 0; b < RADIX; b++) {
				for (Integer i : bucket[b]) {
					input[a++] = i;
				}
				bucket[b].clear();
			}
			placement *= RADIX;
		}
	}
}


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

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

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out){
	    int n = in.ri(), m = in.ri(), res = 0;
	    char[][] tab = IOUtils.readTable(in, n, m);
	    int[][] mem = new int[n][m];
	    for(int row = 0; row < n; row++) {
		    for(int col = m - 1; col >= 0; col--){
			    if (tab[row][col] == '1') mem[row][col] = (col == m - 1) ? 1 : mem[row][col + 1] + 1;
		    }
	    }
	    for(int col = 0; col < m; col++) {
		    int[] curcolvals = new int[n];
		    for(int i = 0; i < n; i++) curcolvals[i] = mem[i][col];
		    ArrayUtils.radixsort(curcolvals);
		    ArrayUtils.reverse(curcolvals);
		    for(int i = 0; i < curcolvals.length; i++) {
			    int howmany = i + 1;
			    int width = curcolvals[i];
			    res = Math.max(res, howmany * width);
		    }
	    }
	    out.printLine(res);

    }
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

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

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

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

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IOUtils {
	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}
	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}
}

class ArrayUtils {
	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}
	public static void radixsort( int[] a)
	{
		int i, m = a[0], exp = 1, n = a.length;
		int[] b = new int[10];
		for (i = 1; i < n; i++)
			if (a[i] > m)
				m = a[i];
		while (m / exp > 0)
		{
			int[] bucket = new int[10];

			for (i = 0; i < n; i++)
				bucket[(a[i] / exp) % 10]++;
			for (i = 1; i < 10; i++)
				bucket[i] += bucket[i - 1];
			for (i = n - 1; i >= 0; i--)
				b[--bucket[(a[i] / exp) % 10]] = a[i];
			for (i = 0; i < n; i++)
				a[i] = b[i];
			exp *= 10;
		}
	}
}